fbo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +27 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +39 -0
  8. data/Rakefile +1 -0
  9. data/fbo.gemspec +30 -0
  10. data/lib/fbo.rb +25 -0
  11. data/lib/fbo/file.rb +14 -0
  12. data/lib/fbo/notice.rb +9 -0
  13. data/lib/fbo/notices.rb +6 -0
  14. data/lib/fbo/notices/amendment.rb +13 -0
  15. data/lib/fbo/notices/award.rb +14 -0
  16. data/lib/fbo/notices/combined_solicitation.rb +14 -0
  17. data/lib/fbo/notices/modification.rb +14 -0
  18. data/lib/fbo/notices/presolicitation.rb +14 -0
  19. data/lib/fbo/notices/sources_sought.rb +13 -0
  20. data/lib/fbo/notices/unknown.rb +7 -0
  21. data/lib/fbo/parser.rb +79 -0
  22. data/lib/fbo/parser/amendment_handler.rb +58 -0
  23. data/lib/fbo/parser/award_handler.rb +62 -0
  24. data/lib/fbo/parser/combined_solicitation_handler.rb +57 -0
  25. data/lib/fbo/parser/modification_handler.rb +66 -0
  26. data/lib/fbo/parser/notice_handler.rb +27 -0
  27. data/lib/fbo/parser/parser_helper.rb +275 -0
  28. data/lib/fbo/parser/presolicitation_handler.rb +57 -0
  29. data/lib/fbo/parser/sources_sought_handler.rb +57 -0
  30. data/lib/fbo/parser/unknown_handler.rb +20 -0
  31. data/lib/fbo/remote_file.rb +39 -0
  32. data/lib/fbo/version.rb +3 -0
  33. data/spec/fbo/file_spec.rb +20 -0
  34. data/spec/fbo/parser/amendment_handler_spec.rb +46 -0
  35. data/spec/fbo/parser/award_handler_spec.rb +51 -0
  36. data/spec/fbo/parser/combined_solicitation_handler_spec.rb +47 -0
  37. data/spec/fbo/parser/modification_handler_spec.rb +47 -0
  38. data/spec/fbo/parser/presolicitation_handler_spec.rb +46 -0
  39. data/spec/fbo/parser/sources_sought_handler_spec.rb +46 -0
  40. data/spec/fbo/parser/unknown_handler_spec.rb +19 -0
  41. data/spec/fbo/parser_spec.rb +85 -0
  42. data/spec/fbo/remote_file_spec.rb +55 -0
  43. data/spec/fixtures/FBOFeed20130331 +5668 -0
  44. data/spec/fixtures/FBOFeed20130404 +45653 -0
  45. data/spec/fixtures/FBOFeed20130406 +10152 -0
  46. data/spec/fixtures/FBOFeed20130407 +6610 -0
  47. data/spec/fixtures/notices/amdcss +26 -0
  48. data/spec/fixtures/notices/award +31 -0
  49. data/spec/fixtures/notices/combine +29 -0
  50. data/spec/fixtures/notices/mod +28 -0
  51. data/spec/fixtures/notices/presol +25 -0
  52. data/spec/fixtures/notices/snote +26 -0
  53. data/spec/fixtures/notices/srcsgt +27 -0
  54. data/spec/spec_helper.rb +23 -0
  55. metadata +154 -0
@@ -0,0 +1,57 @@
1
+ module FBO::Parser::PresolicitationHandler
2
+ TAGS = %w( PRESOL DATE YEAR CBAC PASSWORD ZIP CLASSCOD NAICS OFFADD ) +
3
+ %w( AGENCY OFFICE LOCATION SUBJECT SOLNBR RESPDATE ARCHDATE CONTACT DESC ) +
4
+ %w( LINK URL EMAIL ADDRESS SETASIDE POPADDRESS POPZIP POPCOUNTRY \/PRESOL )
5
+
6
+ ANY_PRESOL_TAG = TAGS.join("|")
7
+ PRESOLICITATION_PATTERN = /^<PRESOL>/
8
+
9
+
10
+ def is_presolicitation?(text)
11
+ text =~ PRESOLICITATION_PATTERN
12
+ end
13
+
14
+ def parse(text)
15
+ params = {
16
+ date: date(text),
17
+ year: year(text),
18
+ zip: zip(text),
19
+ class_code: classification_code(text),
20
+ naics_code: naics_code(text),
21
+ agency: agency(text),
22
+ office: office(text),
23
+ location: location(text),
24
+ office_address: office_address(text),
25
+ subject: subject(text),
26
+ solicitation_number: solicitation_number(text),
27
+ response_date: response_date(text),
28
+ archive_date: archive_date(text),
29
+ contact_info: contact(text),
30
+ description: description(text),
31
+ link_url: link_url(text),
32
+ link_description: link_description(text),
33
+ email_address: email_address(text),
34
+ email_description: email_description(text),
35
+ setaside: set_aside(text),
36
+ pop_address: pop_address(text),
37
+ pop_zip: pop_zip_code(text),
38
+ pop_country: pop_country(text)
39
+ }
40
+ FBO::Notices::Presolicitation.new(params)
41
+ end
42
+
43
+
44
+ protected
45
+
46
+ # Returns a concatenated list of all tags for the notice
47
+ #
48
+ # @return [String]
49
+ def any_notice_tag
50
+ ANY_PRESOL_TAG
51
+ end
52
+
53
+
54
+ extend FBO::Parser::NoticeHandler
55
+ extend FBO::Parser::ParserHelper
56
+ extend self
57
+ end
@@ -0,0 +1,57 @@
1
+ module FBO::Parser::SourcesSoughtHandler
2
+ TAGS = %w( SRCSGT DATE YEAR CBAC PASSWORD ZIP CLASSCOD NAICS OFFADD ) +
3
+ %w( AGENCY OFFICE LOCATION SUBJECT SOLNBR RESPDATE ARCHDATE CONTACT DESC ) +
4
+ %w( LINK URL EMAIL ADDRESS SETASIDE POPADDRESS POPZIP POPCOUNTRY \/SRCSGT )
5
+
6
+ ANY_SRCSGT_TAG = TAGS.join("|")
7
+ SOURCES_SOUGHT_PATTERN = /^<SRCSGT>/
8
+
9
+
10
+ def is_sources_sought?(text)
11
+ text =~ SOURCES_SOUGHT_PATTERN
12
+ end
13
+
14
+ def parse(text)
15
+ params = {
16
+ date: date(text),
17
+ year: year(text),
18
+ zip: zip(text),
19
+ class_code: classification_code(text),
20
+ naics_code: naics_code(text),
21
+ agency: agency(text),
22
+ office: office(text),
23
+ location: location(text),
24
+ office_address: office_address(text),
25
+ subject: subject(text),
26
+ solicitation_number: solicitation_number(text),
27
+ response_date: response_date(text),
28
+ archive_date: archive_date(text),
29
+ contact_info: contact(text),
30
+ description: description(text),
31
+ link_url: link_url(text),
32
+ link_description: link_description(text),
33
+ email_address: email_address(text),
34
+ email_description: email_description(text),
35
+ setaside: set_aside(text),
36
+ pop_address: pop_address(text),
37
+ pop_zip: pop_zip_code(text),
38
+ pop_country: pop_country(text)
39
+ }
40
+ FBO::Notices::SourcesSought.new(params)
41
+ end
42
+
43
+
44
+ protected
45
+
46
+ # Returns a concatenated list of all tags for the notice
47
+ #
48
+ # @return [String]
49
+ def any_notice_tag
50
+ ANY_SRCSGT_TAG
51
+ end
52
+
53
+
54
+ extend FBO::Parser::NoticeHandler
55
+ extend FBO::Parser::ParserHelper
56
+ extend self
57
+ end
@@ -0,0 +1,20 @@
1
+ module FBO::Parser::UnknownHandler
2
+
3
+ def parse(text)
4
+ params = {
5
+ type: type(text),
6
+ text: text
7
+ }
8
+ FBO::Notices::Unknown.new(params)
9
+ end
10
+
11
+
12
+ protected
13
+
14
+ def type(text)
15
+ text =~ /^<([^>]*)>/
16
+ $1
17
+ end
18
+
19
+ extend self
20
+ end
@@ -0,0 +1,39 @@
1
+ require "date"
2
+ require "net/ftp"
3
+
4
+ module FBO
5
+ class RemoteFile < File
6
+ FTP_SERVER = "ftp.fbo.gov"
7
+ TMP_DIR = "/tmp/fbo"
8
+
9
+ class << self
10
+ def for_date(date, options = {})
11
+ filename = filename_for_date(date)
12
+ FBO::RemoteFile.new(filename, options)
13
+ end
14
+
15
+ def filename_for_date(date)
16
+ raise ArgumentError, "No date given for file" unless date
17
+ "FBOFeed#{ date.strftime("%Y%m%d") }"
18
+ end
19
+ end
20
+
21
+ def initialize(filename, options = {})
22
+ @filename = filename
23
+ @tmp_dir = options[:tmp_dir] || TMP_DIR
24
+ @file = fetch_file(filename)
25
+ end
26
+
27
+ protected
28
+
29
+ def fetch_file(filename)
30
+ Dir.mkdir(@tmp_dir) unless Dir.exists?(@tmp_dir)
31
+ tmp_filename = ::File.join(@tmp_dir, filename)
32
+ ftp = Net::FTP.new(FTP_SERVER)
33
+ ftp.login
34
+ ftp.getbinaryfile(filename, tmp_filename)
35
+ ftp.close
36
+ ::File.new(tmp_filename)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module FBO
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::File do
4
+ context "existing file" do
5
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "fixtures", "FBOFeed20130331") }
6
+ subject { FBO::File.new(filename) }
7
+
8
+ it "should be possible to open the file and read its contents" do
9
+ subject.readline.should_not be_nil
10
+ end
11
+ end
12
+
13
+ context "non-existent file" do
14
+ subject { FBO::File.new("foobar.bat") }
15
+
16
+ it "should raise an exception when trying open the file and read its contents" do
17
+ expect { subject.readline }.to raise_error
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::Parser::AmendmentHandler do
4
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "amdcss") }
5
+ let(:file) { File.new(filename) }
6
+ let(:contents) { file.read }
7
+
8
+ subject { FBO::Parser::AmendmentHandler }
9
+
10
+ it "should recognize amendment content" do
11
+ subject.is_amendment?(contents).should be_true
12
+ end
13
+
14
+ it "should parse all fields correctly" do
15
+ combine = subject.parse(contents)
16
+ combine.date.strftime("%Y-%m-%d").should eq Date.parse("2013-03-26").strftime("%Y-%m-%d")
17
+ combine.year.should eq 2013
18
+ combine.agency.should eq "Department of the Air Force"
19
+ combine.office.should eq "Air Force Materiel Command"
20
+ combine.location.should eq "Tinker AFB - OC-ALC/PKO"
21
+ combine.zip.should eq "73145-9106"
22
+ combine.class_code.should eq "R"
23
+ combine.naics_code.should eq "541611"
24
+ combine.office_address.should eq "7858 5th Street Ste 1 Tinker AFB OK 73145-9106"
25
+ combine.subject.should eq "ISO 9001:2008 AS9100/9110 Registration/Surveillance/Reassessment Audit"
26
+ combine.solicitation_number.should eq "FA8101-13-Q-0014"
27
+ combine.response_date.strftime("%Y-%m-%d").should eq "2013-03-27"
28
+ combine.archive_date.strftime("%Y-%m-%d").should eq "2013-04-26"
29
+ combine.contact_info.should eq "Matthew Kinney, Contract Specialist, Phone 4057393745, Email matthew.kinney@tinker.af.mil - Kimberly L DeLong, Contracting Officer, Phone (405) 739-3514, Fax (405) 739-7957, Email kimberly.delong2@tinker.af.mil"
30
+ combine.description.should eq "<p>***All quotes need to be based&nbsp;off of&nbsp;the scope and&nbsp;figures in the&nbsp;PWS and&nbsp;not OASIS<br />***IAW PWS para 1.1(e) the audit will be scheduled in May&nbsp;and must&nbsp;be&nbsp;completed in one week<br />***Organizations&nbsp;OIN 6115237940</p>"
31
+ combine.link_url.should eq "https://www.fbo.gov/spg/USAF/AFMC/OCALCBC/FA8101-13-Q-0014/listing.html"
32
+ combine.link_description.should eq "Link To Document"
33
+ combine.setaside.should eq "Total Small Business"
34
+ combine.pop_country.should eq "US"
35
+ combine.pop_zip.should eq "73145"
36
+ combine.pop_address.should eq "Tinker AFB\nTinker AFB, OK"
37
+ end
38
+
39
+ context "when not a sources sought" do
40
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "presol") }
41
+
42
+ it "should not recognize other notice content" do
43
+ subject.is_amendment?(contents).should_not be_true
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::Parser::AwardHandler do
4
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "award") }
5
+ let(:file) { File.new(filename) }
6
+ let(:contents) { file.read }
7
+
8
+ subject { FBO::Parser::AwardHandler }
9
+
10
+ it "should recognize award content" do
11
+ subject.is_award?(contents).should be_true
12
+ end
13
+
14
+ it "should parse all fields correctly" do
15
+ award = subject.parse(contents)
16
+ award.date.strftime("%Y-%m-%d").should eq Date.parse("2013-03-27").strftime("%Y-%m-%d")
17
+ award.year.should eq 2013
18
+ award.agency.should eq "Department of the Army"
19
+ award.office.should eq "Army Contracting Command, MICC"
20
+ award.location.should eq "MICC - Fort Leonard Wood"
21
+ award.zip.should eq "65473"
22
+ award.class_code.should eq "Z"
23
+ award.naics_code.should eq "238320"
24
+ award.office_address.should eq "MICC - Fort Leonard Wood, Directorate of Contracting, P.O. Box 140, Fort Leonard Wood, MO 65473-0140"
25
+ award.subject.should eq "Z--Painting and General Repairs Requirements for Fort Leonard Wood Military Installation and Lake of the Ozarks Recreation Area, Missouri."
26
+ award.solicitation_number.should eq "W911S713B0002"
27
+ award.notice_type.should eq "PRESOL"
28
+ award.archive_date.strftime("%Y-%m-%d").should eq "2013-04-26"
29
+ award.contact_info.should eq "Christine Wilson, 5735960251\n\n<a href=\"mailto:christine.l.wilson2.civ@mail.mil\">MICC - Fort Leonard Wood</a>"
30
+ award.description.should eq "Painting and General Repairs Requirements for Fort Leonard Wood Military Installation and Lake of the Ozarks Recreation Area, Missouri."
31
+ award.award_number.should eq "W911S713D0003"
32
+ award.award_amount.should eq 10_848_912.50
33
+ award.line_number.should eq "0001"
34
+ award.awardee.should eq "HOWELL & HOWELL CONTRACTORS, INC. (601721483) <br> 2603 GRASSLAND DR <br> LOUISVILLE, KY 40299-2523"
35
+ award.awardee_duns.should eq "1234567890123"
36
+ award.link_url.should eq "https://www.fbo.gov/notices/4f878388ec8ed40badf141d1c0281dae"
37
+ award.link_description.should eq "Link To Document"
38
+ award.email_address.should eq "christine.l.wilson2.civ@mail.mil"
39
+ award.email_description.should eq "MICC - Fort Leonard Wood"
40
+ award.setaside.should be_nil
41
+ award.correction.should be_false
42
+ end
43
+
44
+ context "when not an award" do
45
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "presol") }
46
+
47
+ it "should not recognize other notice content" do
48
+ subject.is_award?(contents).should_not be_true
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::Parser::CombinedSolicitationHandler do
4
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "combine") }
5
+ let(:file) { File.new(filename) }
6
+ let(:contents) { file.read }
7
+
8
+ subject { FBO::Parser::CombinedSolicitationHandler }
9
+
10
+ it "should recognize combined solicitation content" do
11
+ subject.is_combined_solicitation?(contents).should be_true
12
+ end
13
+
14
+ it "should parse all fields correctly" do
15
+ combine = subject.parse(contents)
16
+ combine.date.strftime("%Y-%m-%d").should eq Date.parse("2013-04-07").strftime("%Y-%m-%d")
17
+ combine.year.should eq 2013
18
+ combine.agency.should eq "Defense Logistics Agency"
19
+ combine.office.should eq "DLA Acquisition Locations"
20
+ combine.location.should eq "DLA Aviation - BSM"
21
+ combine.zip.should eq "23297"
22
+ combine.class_code.should eq "61"
23
+ combine.naics_code.should eq "335931"
24
+ combine.office_address.should eq "DLA AVIATION; 8000 JEFFERSON DAVIS HIGHWAY; RICHMOND VA 23297"
25
+ combine.subject.should eq "61--CABLE ASSEMBLY,SPECIAL"
26
+ combine.solicitation_number.should eq "SPE4A613TBW31"
27
+ combine.response_date.strftime("%Y-%m-%d").should eq "2013-04-15"
28
+ combine.archive_date.strftime("%Y-%m-%d").should eq "2013-05-15"
29
+ combine.contact_info.should eq "Questions regarding this solicitation should be emailed to dibbsBSM@dla.mil"
30
+ combine.description.should eq "Proposed procurement for NSN 6150012666487 CABLE ASSEMBLY,SPECIAL:\nLine 0001 Qty 40.00 UI EA Deliver To: W1BG DLA DISTRIBUTION By: 0189 DAYS ADOApproved sources are 56540 75A756180-9AUK; 76301 75A756180-9AUK.\nThe solicitation is an RFQ and will be available at the link provided in this notice. Hard copies of this solicitation are not available. Specifications, plans, or drawings are not available.\nAll responsible sources may submit a quote which, if timely received, shall be considered.\nQuotes must be submitted electronically."
31
+ combine.link_url.should eq "https://www.fbo.gov/spg/DLA/J3/DSCR-BSM/SPE4A613TBW31/listing.html"
32
+ combine.link_description.should eq "Link To Document"
33
+ combine.setaside.should eq "Total Small Business"
34
+ combine.pop_country.should eq "US"
35
+ combine.pop_zip.should eq "20005-4026"
36
+ combine.pop_address.should eq "Washington, DC 20005"
37
+
38
+ end
39
+
40
+ context "when not a combined solicitation" do
41
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "presol") }
42
+
43
+ it "should not recognize other notice content" do
44
+ subject.is_combined_solicitation?(contents).should_not be_true
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::Parser::ModificationHandler do
4
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "mod") }
5
+ let(:file) { File.new(filename) }
6
+ let(:contents) { file.read }
7
+
8
+ subject { FBO::Parser::ModificationHandler }
9
+
10
+ it "should recognize modification content" do
11
+ subject.is_modification?(contents).should be_true
12
+ end
13
+
14
+ it "should parse all fields correctly" do
15
+ mod = subject.parse(contents)
16
+ mod.date.strftime("%Y-%m-%d").should eq Date.parse("2013-03-27").strftime("%Y-%m-%d")
17
+ mod.year.should eq 2013
18
+ mod.agency.should eq "Department of Agriculture"
19
+ mod.office.should eq "Agricultural Research Service"
20
+ mod.location.should eq "ARS EBSC APB DM"
21
+ mod.zip.should eq "20705"
22
+ mod.class_code.should eq "66"
23
+ mod.naics_code.should eq "811219"
24
+ mod.office_address.should eq "5601 Sunnyside Avenue Beltsville MD 20705"
25
+ mod.subject.should eq "Maintenance/Service contract (Plus 2 Option years) for a \"ELAN DRC E Inductively Coupled Spectrometer\""
26
+ mod.solicitation_number.should eq "625715"
27
+ mod.notice_type.should eq "SNOTE"
28
+ mod.response_date.strftime("%Y-%m-%d").should eq "2013-04-01"
29
+ mod.archive_date.should be_nil
30
+ mod.contact_info.should eq "John C. Wilkinson, Purchasing Agent, Phone 301-504-1731, Email john.wilkinson@ars.usda.gov - Rene D. Edwards, Contract Specialist, Phone 301 504-1744, Email rene.edwards@ars.usda.gov"
31
+ mod.description.should eq "&nbsp;\n<p><span style=\"COLOR: #1f497d\">___________________________________________________________________________________________________________________</span></p>\n<p>&nbsp;THIS IS AN AMENDMENT TO ADD THE ADDITIONAL VERBIAGE&nbsp;AS&nbsp;A&nbsp; CRITICAL MINIMUM&nbsp;REQUIREMENT&nbsp;FOR&nbsp;&nbsp;THE FOLLOWING SERVICE CONTRACT REQUIREMENT: &nbsp;\"GUARANTEE\" OF&nbsp;A CERTIFIED ENGINEER'S PHONE RESPONSE TO U.S. DEPARTMENT OF AGRICULTURE (USDA'S)&nbsp;REQUEST&nbsp;&nbsp;WITHIN 24 HOURS OF A &nbsp;USDA CUSTOMER PLACING A SERVICE CALL.&nbsp;PLEASE ALSO NOTE THE CORRECTED TIME FRAME OF THE ANTICIPATED AWARD DATE BEING APRIL 3, 2013 AND THE QUOTES DUE NO LATER TO ME: JOHN WILKINSON&nbsp; AT USDA BY CLOSE OF BUSINESS APRIL 1, 2013 TO <a href=\"mailto:JOHN.WILKINSON@ARS.USDA.GOV\">JOHN.WILKINSON@ARS.USDA.GOV</a> AT PHONE # 301-504-1731.</p>\n<p>U.S. Department of Agriculture, Agriculture Research Service in Beltsville, Maryland intends to award a <span style=\"COLOR: #1f497d\">(yearly maintenance plus 2 option years) </span>contract<span style=\"COLOR: #1f497d\"> as a sole source award &nbsp;for the following instrument: &nbsp;\"ICP-MS Elan DRC E\" instrument, Serial Number: AH00430510 located in Beltsville, Maryland, &nbsp;that is manufactured by Perkin Elmer Health Sciences, Inc.</span> , located in <span style=\"COLOR: #1f497d\">Shelton, Connecticut.&nbsp;&nbsp; &nbsp;The following are the requirements of this service contract:&nbsp;&nbsp; Personnel that performs service on the above instrument, must be able to demonstrate that they are trained,&nbsp; in testing, service and software support, for this instrument, and can replace internal parts of this equipment.&nbsp; The repair coverage for the above instrument will include: Parts, Components, &nbsp;labor, travel, and phone support.&nbsp;&nbsp; Perkin Elmer Health Sciences, Inc. is the sole source provider for factory new or factory re-manufactured parts, local service representation and factory trained/certified engineers to provide service and installation for all instrumentation &nbsp;manufactured and sold by Perkin Elmer, Inc.&nbsp;&nbsp; Perkin Elmer does not certify third party technical service nor does Perkin Elmer have any dealers or distributors selling parts.&nbsp; &nbsp;&nbsp;The base year of this maintenance contract will run from April 3, 2013&nbsp; to March 26, 2014, then option year I would run from March 27, 2014 to March 26, 2015 and Option Year II would run from March 27, 2015 to March 26, 2016</span></p>"
32
+ mod.link_url.should eq "https://www.fbo.gov/notices/9189b266ca1710152c807950c8b13cbe"
33
+ mod.link_description.should eq "Link To Document"
34
+ mod.setaside.should eq "N/A"
35
+ mod.pop_country.should eq "US"
36
+ mod.pop_zip.should be_nil
37
+ mod.pop_address.should eq "USDA, ARS, EMBUL, BARC\n10300 BALTIMORE AVE.\nBeltsville, MD"
38
+ end
39
+
40
+ context "when not a modification" do
41
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "presol") }
42
+
43
+ it "should not recognize other notice content" do
44
+ subject.is_modification?(contents).should_not be_true
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe FBO::Parser::PresolicitationHandler do
4
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "presol") }
5
+ let(:file) { File.new(filename) }
6
+ let(:contents) { file.read }
7
+
8
+ subject { FBO::Parser::PresolicitationHandler }
9
+
10
+ it "should recognize presolication content" do
11
+ subject.is_presolicitation?(contents).should be_true
12
+ end
13
+
14
+ it "should parse all fields correctly" do
15
+ presol = subject.parse(contents)
16
+ presol.date.strftime("%Y-%m-%d").should eq Date.parse("2013-03-31").strftime("%Y-%m-%d")
17
+ presol.year.should eq 2013
18
+ presol.agency.should eq "Defense Logistics Agency"
19
+ presol.office.should eq "DLA Acquisition Locations"
20
+ presol.location.should eq "DLA Aviation - BSM"
21
+ presol.zip.should eq "23297-5000"
22
+ presol.class_code.should eq "15"
23
+ presol.naics_code.should eq "336412"
24
+ presol.office_address.should eq "8000 Jefferson Davis Highway Richmond VA 23297-5000"
25
+ presol.subject.should eq "Seal, AFT; F108-CF100"
26
+ presol.solicitation_number.should eq "SPE4A713R0795"
27
+ presol.response_date.strftime("%Y-%m-%d").should eq "2013-05-15"
28
+ presol.contact_info.should eq "Heidi LaCosse, Acquisition Specialist, Phone 8042793395, Fax 8042792314, Email heidi.lacosse@dla.mil - Amanda M Parker, Acquisition Supervisor, Phone (804)279-2326, Fax (804)279-4722, Email amanda.parker@dla.mil"
29
+ presol.description.should eq "&nbsp;\n<p>PR# 49250123; NSN 2840-01-183-1908; Firm Fixed Price; Definite Quantity Contract; Unrestricted Acquisition; Other Than Full and Open Competition; The only approved manufacturing sources are Jet Avion, Cage 14236 and CFM International, Cage 58828;<span style=\"mso-spacerun: yes\">&nbsp; </span>Seal, Aft; Critical Application Item; Configuration Control Applies; Government FAT; Quantity of 3929 units; Inspection/Acceptance at Origin; FOB at Origin; Requested delivery is 450 days after receipt of order; Electronic Offers are not acceptable; Progress Payments are not offered as the conditions at FAR 32.5 have not been met; Any manufacturer, other than the approved source, wishing to submit a proposal on this item must submit a complete source approval package and a complete solicitation package; A copy of the solicitation will be available via DIBBS at <a href=\"https://www.dibbs.bsm.dla.mil/RFP\"><span style=\"mso-ansi-font-size: 12.0pt\">https://www.dibbs.bsm.dla.mil/RFP</span></a> on the issue date cited in this synopsis.<span style=\"mso-spacerun: yes\">&nbsp; </span>RFP's are in portable document format (PDF).<span style=\"mso-spacerun: yes\">&nbsp; </span>To download and view these documents you will need the latest version of Adobe Acrobat.<span style=\"mso-spacerun: yes\">&nbsp; </span>This software is available free at http://www.adobe.com.<span style=\"mso-spacerun: yes\">&nbsp; </span>A paper copy of this solicitation will be available to requesters.<span style=\"mso-spacerun: yes\">&nbsp; </span>The solicitation issue date is April 15, 2013.</p>"
30
+ presol.link_url.should eq "https://www.fbo.gov/spg/DLA/J3/DSCR-BSM/SPE4A713R0795/listing.html"
31
+ presol.link_description.should eq "Link To Document"
32
+ presol.setaside.should eq "N/A"
33
+ presol.pop_country.should eq "US"
34
+ presol.pop_zip.should eq "23297"
35
+ presol.pop_address.should eq "8000 Jefferson Davis Highway\nRichmonda, VA"
36
+
37
+ end
38
+
39
+ context "when not a presolication" do
40
+ let(:filename) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "notices", "combine") }
41
+
42
+ it "should not recognize other notice content" do
43
+ subject.is_presolicitation?(contents).should_not be_true
44
+ end
45
+ end
46
+ end