apdm 0.0.15

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 (139) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/README.md +223 -0
  6. data/Rakefile +1 -0
  7. data/apdm.gemspec +34 -0
  8. data/bin/apdm +6 -0
  9. data/features/ad_tech.feature +11 -0
  10. data/features/step_definitions/ad_tech_steps.rb +19 -0
  11. data/features/support/env.rb +5 -0
  12. data/fixtures/approvals/ad_tech_loader_scripts.approved.txt +42 -0
  13. data/fixtures/approvals/ad_tech_placeholders.approved.txt +6 -0
  14. data/lib/apdm.rb +24 -0
  15. data/lib/apdm/ad_tech.rb +96 -0
  16. data/lib/apdm/ad_tech/ad_loader.rb +67 -0
  17. data/lib/apdm/ad_tech/ads.csv +475 -0
  18. data/lib/apdm/ad_tech/data.rb +47 -0
  19. data/lib/apdm/channel.rb +87 -0
  20. data/lib/apdm/channels.rb +569 -0
  21. data/lib/apdm/credentials.rb +26 -0
  22. data/lib/apdm/design_elements.rb +60 -0
  23. data/lib/apdm/design_elements/api.rb +75 -0
  24. data/lib/apdm/feed.rb +65 -0
  25. data/lib/apdm/issues.rb +14 -0
  26. data/lib/apdm/issues/aasavis.rb +51 -0
  27. data/lib/apdm/issues/amta.rb +253 -0
  28. data/lib/apdm/issues/an.rb +302 -0
  29. data/lib/apdm/issues/auraavis.rb +154 -0
  30. data/lib/apdm/issues/austagderblad.rb +154 -0
  31. data/lib/apdm/issues/avisa-hordaland.rb +154 -0
  32. data/lib/apdm/issues/avisa-valdres.rb +177 -0
  33. data/lib/apdm/issues/ba.rb +352 -0
  34. data/lib/apdm/issues/bladet.rb +154 -0
  35. data/lib/apdm/issues/blv.rb +254 -0
  36. data/lib/apdm/issues/bygdeposten.rb +154 -0
  37. data/lib/apdm/issues/demokraten.rb +154 -0
  38. data/lib/apdm/issues/eikerbladet.rb +409 -0
  39. data/lib/apdm/issues/enebakkavis.rb +51 -0
  40. data/lib/apdm/issues/etl.rb +79 -0
  41. data/lib/apdm/issues/eub.rb +254 -0
  42. data/lib/apdm/issues/finnmarkdagblad.rb +302 -0
  43. data/lib/apdm/issues/finnmarken.rb +302 -0
  44. data/lib/apdm/issues/firda.rb +302 -0
  45. data/lib/apdm/issues/firdaposten.rb +153 -0
  46. data/lib/apdm/issues/fremover.rb +304 -0
  47. data/lib/apdm/issues/gd.rb +304 -0
  48. data/lib/apdm/issues/glomdalen.rb +302 -0
  49. data/lib/apdm/issues/ha-halden.rb +302 -0
  50. data/lib/apdm/issues/hadeland.rb +251 -0
  51. data/lib/apdm/issues/hardanger-folkeblad.rb +151 -0
  52. data/lib/apdm/issues/helgeland-arbeiderblad.rb +304 -0
  53. data/lib/apdm/issues/import.csv +12821 -0
  54. data/lib/apdm/issues/indre.rb +151 -0
  55. data/lib/apdm/issues/jarlsbergavis.rb +154 -0
  56. data/lib/apdm/issues/kvinnheringen.rb +202 -0
  57. data/lib/apdm/issues/lofot-tidende.rb +102 -0
  58. data/lib/apdm/issues/lofotposten.rb +304 -0
  59. data/lib/apdm/issues/mb.rb +103 -0
  60. data/lib/apdm/issues/namdalsavisa.rb +302 -0
  61. data/lib/apdm/issues/nordhordland.rb +103 -0
  62. data/lib/apdm/issues/nordlys.rb +304 -0
  63. data/lib/apdm/issues/oa.rb +302 -0
  64. data/lib/apdm/issues/op.rb +304 -0
  65. data/lib/apdm/issues/opdalingen.rb +150 -0
  66. data/lib/apdm/issues/oyene.rb +51 -0
  67. data/lib/apdm/issues/pd.rb +254 -0
  68. data/lib/apdm/issues/r-a.rb +152 -0
  69. data/lib/apdm/issues/ranablad.rb +304 -0
  70. data/lib/apdm/issues/rb.rb +302 -0
  71. data/lib/apdm/issues/retten.rb +151 -0
  72. data/lib/apdm/issues/ringblad.rb +304 -0
  73. data/lib/apdm/issues/rogalandsavis.rb +302 -0
  74. data/lib/apdm/issues/sa.rb +304 -0
  75. data/lib/apdm/issues/smaalenene.rb +304 -0
  76. data/lib/apdm/issues/sognavis.rb +254 -0
  77. data/lib/apdm/issues/ta.rb +304 -0
  78. data/lib/apdm/issues/tk.rb +304 -0
  79. data/lib/apdm/issues/tvedestrandsposten.rb +150 -0
  80. data/lib/apdm/issues/vestbyavis.rb +51 -0
  81. data/lib/apdm/local_paper_area.rb +21 -0
  82. data/lib/apdm/network.rb +49 -0
  83. data/lib/apdm/null_cache.rb +15 -0
  84. data/lib/apdm/origo.rb +46 -0
  85. data/lib/apdm/saxo.rb +58 -0
  86. data/lib/apdm/saxo/iptc.rb +69 -0
  87. data/lib/apdm/saxo/metadata.rb +36 -0
  88. data/lib/apdm/saxo/remote.rb +67 -0
  89. data/lib/apdm/sinatra.rb +85 -0
  90. data/lib/apdm/version.rb +3 -0
  91. data/lib/cli.rb +12 -0
  92. data/spec/ad_tech/ad_loader_spec.rb +27 -0
  93. data/spec/ad_tech/data_spec.rb +14 -0
  94. data/spec/ad_tech_spec.rb +70 -0
  95. data/spec/approvals_helper.rb +6 -0
  96. data/spec/channel_spec.rb +91 -0
  97. data/spec/channels_spec.rb +9 -0
  98. data/spec/credentials_integration_spec.rb +13 -0
  99. data/spec/credentials_spec.rb +34 -0
  100. data/spec/design_elements_spec.rb +132 -0
  101. data/spec/feed_spec.rb +49 -0
  102. data/spec/fixtures/ad_tech.csv +6 -0
  103. data/spec/fixtures/approvals/adtech/ad_loader.approved.txt +9 -0
  104. data/spec/fixtures/approvals/apdm_adtech/data/handles_artikkelboard.approved.txt +10 -0
  105. data/spec/fixtures/approvals/apdm_adtech/data/handles_bunnbanner.approved.txt +10 -0
  106. data/spec/fixtures/approvals/apdm_adtech/data/handles_skyskraper_1.approved.txt +10 -0
  107. data/spec/fixtures/approvals/apdm_adtech/data/handles_toppbanner.approved.txt +10 -0
  108. data/spec/fixtures/approvals/apdm_adtech/data/is_ok_with_new_bandwagon_data.approved.txt +10 -0
  109. data/spec/fixtures/approvals/apdm_adtech/data/loads_default_data.approved.txt +10 -0
  110. data/spec/fixtures/approvals/apdm_designelements/css/via_api.approved.txt +23 -0
  111. data/spec/fixtures/approvals/apdm_designelements/footer_html/via_api.approved.html +85 -0
  112. data/spec/fixtures/approvals/apdm_designelements/header_html/via_api.approved.html +40 -0
  113. data/spec/fixtures/approvals/apdm_designelements/tracking_scripts/api/keyword.approved.txt +54 -0
  114. data/spec/fixtures/approvals/apdm_designelements/tracking_scripts/api/placeholder.approved.txt +54 -0
  115. data/spec/fixtures/issues.csv +3 -0
  116. data/spec/fixtures/test.jpg +0 -0
  117. data/spec/fixtures/vcr_cassettes/apdm_credentials.yml +44 -0
  118. data/spec/fixtures/vcr_cassettes/css.yml +5588 -0
  119. data/spec/fixtures/vcr_cassettes/footer-html.yml +178 -0
  120. data/spec/fixtures/vcr_cassettes/header-html.yml +132 -0
  121. data/spec/fixtures/vcr_cassettes/origo_someone_credentials.yml +43 -0
  122. data/spec/fixtures/vcr_cassettes/origo_westerdal_credentials.yml +56 -0
  123. data/spec/fixtures/vcr_cassettes/site_stat.yml +172 -0
  124. data/spec/fixtures/vcr_cassettes/site_stat_custom_category.yml +172 -0
  125. data/spec/geo_spec.rb +10 -0
  126. data/spec/issues_etl_spec.rb +41 -0
  127. data/spec/mockcached.rb +36 -0
  128. data/spec/network_spec.rb +43 -0
  129. data/spec/null_cache_spec.rb +29 -0
  130. data/spec/origo_spec.rb +24 -0
  131. data/spec/saxo/iptc_spec.rb +105 -0
  132. data/spec/saxo/metadata_spec.rb +79 -0
  133. data/spec/saxo/remote_spec.rb +71 -0
  134. data/spec/saxo/saxo_spec.rb +82 -0
  135. data/spec/spec_helper.rb +22 -0
  136. data/spec/vcr_helper.rb +6 -0
  137. data/test/fixtures/config-example.yml +6 -0
  138. data/test/saxo/acceptance_spec.rb +109 -0
  139. metadata +427 -0
@@ -0,0 +1,172 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://www.avisnavn.no/?app=default&counterName=awesomesauce&element=traffic&key=automated-test-key&service=designElements&version=4
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ X-Trace-App:
16
+ - ! '[relax ; blixt.api.kunder.linpro.no ; Sat Apr 28 15:14:03 CEST 2012]'
17
+ - ! '[relax ; knuff.api.kunder.linpro.no ; Sat Apr 28 15:14:03 CEST 2012]'
18
+ - ! '[seamstress ; glitter.api.kunder.linpro.no ; Sat Apr 28 15:19:04 CEST 2012]'
19
+ X-Ua-Compatible:
20
+ - IE=Edge
21
+ Content-Language:
22
+ - nb-NO-www.avisnavn.no
23
+ Content-Type:
24
+ - text/html; charset=utf-8
25
+ Server:
26
+ - Jetty(6.1.24)
27
+ X-Varnish:
28
+ - '1596279391'
29
+ - '2243642635'
30
+ Via:
31
+ - 1.1 varnish
32
+ - 1.1 varnish
33
+ X-Src-Webcache:
34
+ - regolit.api.kunder.linpro.no glitter
35
+ Transfer-Encoding:
36
+ - chunked
37
+ Date:
38
+ - Sat, 28 Apr 2012 13:19:04 GMT
39
+ Age:
40
+ - '0'
41
+ Connection:
42
+ - keep-alive
43
+ Cache-Control:
44
+ - must-revalidate
45
+ X-Country-Code:
46
+ - 'NO'
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ! '<!-- PATH: -->
50
+
51
+ <!-- Spring Score : start -->
52
+
53
+ <script type="text/javascript" src="http://r.api.no/local/v3/common/js/spring/spring.js">
54
+ </script>
55
+
56
+ <script type="text/javascript">
57
+
58
+ <!--
59
+
60
+ var api_sp_e02 = {
61
+
62
+ "s":"api",
63
+
64
+ "cp":"API/www.avisnavn.no",
65
+
66
+ "url": "http://www.avisnavn.no/designelement"
67
+
68
+ }
69
+
70
+ spring.c(api_sp_e02);
71
+
72
+ //-->
73
+
74
+ </script>
75
+
76
+ <noscript><img src="http://api.tns-cs.net/j0=,,,;+,cp=API/www.avisnavn.no+url=http%3A%2F%2Fwww.avisnavn.no%2Fdesignelement;;;"
77
+ alt=""></noscript>
78
+
79
+ <!-- Spring Score : end -->
80
+
81
+ <!--
82
+
83
+ Cache-Control: max-age=86400, groups=/componada-dold, /relax-blixt, /pub2463514,
84
+ /ece_frontpage, /com-global-traffic_tns, /sec39688
85
+
86
+ X-Trace-App: [componada ; dold.api.kunder.linpro.no ; Sat Apr 28 15:14:03
87
+ CEST 2012]
88
+
89
+ X-Trace-App: [relax ; blixt.api.kunder.linpro.no ; Sat Apr 28 13:05:37 CEST
90
+ 2012]
91
+
92
+ -->
93
+
94
+ <img src="http://cachetest.api.no/pix.gif" width="1" height="1" alt="">
95
+
96
+ <!--
97
+
98
+ Cache-Control: max-age=86400, groups=/componada-drag, /static, /com-global-traffic_apipix
99
+
100
+ X-Trace-App: [componada ; drag.api.kunder.linpro.no ; Sat Apr 28 07:16:35
101
+ CEST 2012]
102
+
103
+ -->
104
+
105
+ <!-- Begin Sitestat4 code -->
106
+
107
+ <script language="JavaScript1.1" type="text/javascript">
108
+
109
+ <!--
110
+
111
+ function sitestat(u){
112
+
113
+ var d=document,l=d.location;
114
+
115
+ u += "&ns__t="+(new Date().getTime());
116
+
117
+ // Gets the search result total from the search_results component
118
+
119
+ if(typeof ns_searchResults != "undefined")if(ns_searchResults)u += "&amp;ns_search_result="
120
+ + ns_searchResults;
121
+
122
+ ns_pixelUrl = u;
123
+
124
+ u=ns_pixelUrl+"&ns_c="+((d.characterSet)?d.characterSet:d.defaultCharset)+"&ns_ti="+escape(d.title)+"&ns_jspageurl="+escape(l&&l.href?l.href:d.URL)+"&ns_referrer="+escape(d.referrer);
125
+
126
+ (d.images)?new Image().src=u:d.write(''<''+''p><img src="''+u+''" height="1"
127
+ width="1" alt="*"><''+''/p>'');
128
+
129
+ }
130
+
131
+ fullStatUrl = ''http://int.sitestat.com/a-pi/x/s?awesomesauce&amp;category='';
132
+
133
+ sitestat(fullStatUrl);
134
+
135
+ // Used in click in / out scripts.
136
+
137
+ var nedstat_site = ''x'';
138
+
139
+ var nedstat_siteHost = ''http://www.avisnavn.no'';
140
+
141
+ var nedstat_active = ''true'';
142
+
143
+ //-->
144
+
145
+ </script>
146
+
147
+ <noscript>
148
+
149
+ <img src="http://int.sitestat.com/a-pi/x/s?awesomesauce&amp;category=" width="1"
150
+ height="1" alt="">
151
+
152
+ </noscript>
153
+
154
+ <!-- End Sitestat code -->
155
+
156
+ <!--
157
+
158
+ Cache-Control: max-age=86400, groups=/componada-glitter, /relax-blixt, /pub2463514,
159
+ /ece_frontpage, /com-global-traffic_nedstat_section, /sec39688
160
+
161
+ X-Trace-App: [componada ; glitter.api.kunder.linpro.no ; Sat Apr 28 15:19:04
162
+ CEST 2012]
163
+
164
+ X-Trace-App: [relax ; blixt.api.kunder.linpro.no ; Sat Apr 28 13:05:37 CEST
165
+ 2012]
166
+
167
+ -->
168
+
169
+ '
170
+ http_version:
171
+ recorded_at: Sat, 28 Apr 2012 13:19:05 GMT
172
+ recorded_with: VCR 2.0.1
@@ -0,0 +1,10 @@
1
+ require 'apdm/local_paper_area'
2
+
3
+ describe APDM::LocalPaperArea do
4
+
5
+ let(:geo) { "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[12.1234130859375,63.1046997471211],[11.865234375,63.1071845371386],[11.5960693359375,63.1593160714105],[11.4202880859375,63.1717145457086],[11.35986328125,63.1469122928484],[11.239013671875,63.1096691147021],[11.1236572265625,63.0375300597363],[11.00830078125,62.9951584521205],[10.9149169921875,62.8175283202214],[10.72265625,62.7496959510699],[10.7391357421875,62.5983974391559],[10.74462890625,62.5021745599426],[10.78857421875,62.4030956316363],[10.5029296875,62.3343099292011],[10.12939453125,62.2065118984177],[9.854736328125,62.0858865828731],[10.0579833984375,61.9905877362041],[10.3765869140625,61.8924020831161],[10.5084228515625,61.7731228645315],[10.78857421875,61.7002908383263],[11.05224609375,61.6585951742643],[11.260986328125,61.556725885809],[11.2664794921875,61.4728903088153],[11.5191650390625,61.4230058983234],[11.7169189453125,61.7054988381964],[11.678466796875,62.1218677921369],[11.88720703125,62.2704786971012],[12.0355224609375,62.3547073258179],[12.2332763671875,62.3598045100388],[12.0684814453125,62.6110351962702],[12.1728515625,62.9502272814474],[12.1234130859375,63.1046997471211],[12.1234130859375,63.1046997471211],[12.1234130859375,63.1046997471211],[12.1234130859375,63.1046997471211],[12.1234130859375,63.1046997471211]]]]}" }
6
+
7
+ subject { APDM::LocalPaperArea.new(geo) }
8
+ it { subject.contains?(11.660385, 62.629982).should be_true } # røros
9
+ it { subject.contains?(5.857244, 61.45325).should be_false } # førde
10
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ require 'apdm/issues/etl'
3
+
4
+ describe APDM::Issues::ETL do
5
+
6
+ subject { APDM::Issues::ETL }
7
+
8
+ context "with a sane import source" do
9
+ let(:glom) { { 'www.glomdalen.no' => ['2012-01-01', '2012-01-02'] } }
10
+ let(:avisnavn) { { 'www.avisnavn.no' => ['2012-01-01'] } }
11
+
12
+ it "extracts" do
13
+ subject.extract('spec/fixtures/issues.csv').should eq(glom.merge(avisnavn))
14
+ end
15
+
16
+ it "transforms" do
17
+ channel, issues = subject.transform('www.avisnavn.no', ['2012-01-01'])
18
+
19
+ channel.should eq APDM::Channel.find('avisnavn')
20
+ issues.should eq [Date.new(2012, 1, 1)]
21
+ end
22
+ end
23
+
24
+ context "when unable to match issues to a channel" do
25
+ it "complains" do
26
+ ->{ subject.transform('www.no-such-paper.no', []) }.should raise_error APDM::Issues::ETL::NoMatchingChannel
27
+ end
28
+ end
29
+
30
+ describe "the full import" do
31
+ # NOTE: I am not convinced about the structure of this.
32
+ it "works" do
33
+ subject.stub(:path).and_return '/tmp/1.rb', '/tmp/2.rb'
34
+ subject.import('spec/fixtures/issues.csv')
35
+
36
+ File.read('/tmp/1.rb').should eq("APDM::ISSUES['glomdalen'] = [\n Date.parse('2012-01-01'),\n Date.parse('2012-01-02')\n]\n")
37
+ File.read('/tmp/2.rb').should eq("APDM::ISSUES['avisnavn'] = [\n Date.parse('2012-01-01')\n]\n")
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,36 @@
1
+ class Mockcached
2
+
3
+ def initialize
4
+ @store = {}
5
+ end
6
+
7
+ def set(*args)
8
+ @store[args[0]] = args[1]
9
+ end
10
+
11
+ def get(*args)
12
+ @store[args[0]]
13
+ end
14
+
15
+ def fetch(*args)
16
+ set args[0], yield
17
+ end
18
+
19
+ def get_multi(*keys)
20
+ result = {}
21
+ keys.each do |key|
22
+ value = get(key)
23
+ result[key] = value if value
24
+ end
25
+ result
26
+ end
27
+
28
+ def multi
29
+ yield
30
+ end
31
+
32
+ def delete(*args)
33
+ @store.delete(args[0])
34
+ end
35
+
36
+ end
@@ -0,0 +1,43 @@
1
+ require 'apdm/network'
2
+
3
+ describe APDM::Network do
4
+ subject { APDM::Network.new }
5
+
6
+ let(:abc) { stub(:label => 'abc') }
7
+ let(:prq) { stub(:label => 'prq') }
8
+ let(:xyz) { stub(:label => 'xyz') }
9
+
10
+ it "can append channels" do
11
+ subject << xyz
12
+ subject.channels.should eq([xyz])
13
+ end
14
+
15
+ context "with several channels" do
16
+ before :each do
17
+ subject << abc << prq << xyz
18
+ end
19
+
20
+ it "finds a channel by label" do
21
+ subject.find_by_label('prq').should eq(prq)
22
+ end
23
+
24
+ describe "find" do
25
+ specify "by domain" do
26
+ subject.find_by_url('prq.no').should eq(prq)
27
+ end
28
+
29
+ specify "with some random subdomain" do
30
+ subject.find_by_url('auda.mobil.prq.no').should eq(prq)
31
+ end
32
+
33
+ specify "by homepage" do
34
+ subject.find_by_url('http://www.prq.no').should eq(prq)
35
+ end
36
+
37
+ specify "by homepage with secure protocol" do
38
+ subject.find_by_url('https://www.prq.no').should eq(prq)
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,29 @@
1
+ require 'apdm'
2
+
3
+ describe APDM::NullCache do
4
+ before(:each) do
5
+ APDM.cache = nil
6
+ end
7
+
8
+ it "does nothing on set" do
9
+ ->{ subject.set('whatever', 'stuff', :expires_in => 23) }.should_not raise_error
10
+ end
11
+
12
+ it "does nothing on get" do
13
+ ->{ subject.get('whatever') }.should_not raise_error
14
+ end
15
+
16
+ it "does nothing on delete" do
17
+ ->{ subject.delete('whatever') }.should_not raise_error
18
+ end
19
+
20
+ it "is apdm's default cache" do
21
+ ->{ APDM.cache.get('whatever') }.should_not raise_error
22
+ end
23
+
24
+ it "can be overridden" do
25
+ cache = stub(:cache, :get => 'hey')
26
+ APDM.cache = cache
27
+ APDM.cache.get('something').should eq('hey')
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'vcr_helper'
3
+ require 'apdm/origo'
4
+
5
+ describe APDM::Origo do
6
+
7
+ it "determines whether a organization id is an APDM organization" do
8
+ APDM::Origo.organization?(1).should == false
9
+ APDM::Origo.organization?(44).should == true
10
+ end
11
+
12
+ it "actually talks to origo" do
13
+ VCR.use_cassette('origo.someone.credentials') do
14
+ credentials = APDM::Origo.fetch_credentials(4111).first
15
+ credentials["role"].should == "Redaktør"
16
+ end
17
+ end
18
+
19
+ it "filters out non-a-pressen credentials" do
20
+ VCR.use_cassette('origo.westerdal.credentials') do
21
+ APDM::Origo.fetch_credentials(1034291).should eq([])
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,105 @@
1
+ require 'simplecov'
2
+ require 'apdm/saxo/iptc'
3
+
4
+ describe APDM::Saxo::IPTC do
5
+ before :each do
6
+ APDM::Saxo::IPTC.any_instance.stub(:logger) { stub.as_null_object }
7
+ end
8
+
9
+ describe "target file" do
10
+ subject { APDM::Saxo::IPTC.new('name', 'path') }
11
+ its(:name) { should eq('name') }
12
+ its(:path) { should eq('path') }
13
+ end
14
+
15
+ describe "manipulating the file" do
16
+
17
+ let(:fullpath) { File.expand_path('../../fixtures', __FILE__) }
18
+ let(:testfile) { "#{fullpath}/test.jpg" }
19
+ let(:tmpfile) { "#{fullpath}/tmp.jpg" }
20
+
21
+ subject { APDM::Saxo::IPTC.new('tmp.jpg', fullpath) }
22
+
23
+ before :each do
24
+ FileUtils.cp testfile, tmpfile
25
+ # guard
26
+ `exiv2 -Pnv #{tmpfile}`.gsub(/^ObjectName/, "").strip.should eq("Old Object Name")
27
+ end
28
+
29
+ after :each do
30
+ File.delete tmpfile
31
+ end
32
+
33
+ it "deletes existing data" do
34
+ subject.delete_metadata
35
+ `exiv2 -Pnv #{tmpfile}`.should eq("")
36
+ end
37
+
38
+ describe "writing metadata" do
39
+ it "writes the file name into ObjectName" do
40
+ subject.write_metadata
41
+ `exiv2 -Pnv #{tmpfile}`.gsub(/^ObjectName/, "").strip.should eq('tmp.jpg')
42
+ end
43
+
44
+ [:keywords, :byline, :headline, :credit, :source, :copyright, :caption].each do |key|
45
+ it "writes the #{key.inspect} into #{key.to_s.capitalize}" do
46
+ subject.write_metadata(key => key.to_s)
47
+ `exiv2 -Pnv #{tmpfile}`.split("\n").last.gsub(/#{key.to_s.capitalize}/, '').strip.should eq(key.to_s)
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ describe "source photo" do
55
+ it "is optionally included" do
56
+ photo = APDM::Saxo::IPTC.new('name', 'path', :source => 'url')
57
+ photo.source.should eq('url')
58
+ end
59
+ end
60
+
61
+ describe "#download" do
62
+ subject { APDM::Saxo::IPTC.new('name', 'path', :source => 'url') }
63
+
64
+ it "opens the file" do
65
+ File.should_receive(:open).with('path/name', 'wb')
66
+ subject.download
67
+ end
68
+
69
+ it "does other stuff which is exceedingly difficult to test"
70
+ end
71
+
72
+ describe "#write" do
73
+ it "downloads the file" do
74
+ photo = APDM::Saxo::IPTC.new('name', 'path', :source => 'url')
75
+ photo.should_receive(:download)
76
+ photo.write
77
+ end
78
+
79
+ context "with an existing file" do
80
+ let(:photo) { APDM::Saxo::IPTC.new('name', 'path') }
81
+
82
+ before(:each) do
83
+ photo.stub(:download)
84
+ photo.stub(:delete_metadata)
85
+ photo.stub(:write_metadata)
86
+ end
87
+
88
+ it "doesn't download if there is no specified source" do
89
+ photo.should_not_receive(:download)
90
+ photo.write
91
+ end
92
+
93
+ it "deletes existing metadata" do
94
+ photo.should_receive(:delete_metadata)
95
+ photo.write
96
+ end
97
+
98
+ it "writes the metadata" do
99
+ data = stub(:metadata)
100
+ photo.should_receive(:write_metadata).with(data)
101
+ photo.write(data)
102
+ end
103
+ end
104
+ end
105
+ end