mailshake-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/mailshake.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httparty'
4
+ require 'json'
5
+
6
+ require_relative 'mailshake/version'
7
+ require_relative 'mailshake/errors'
8
+ require_relative 'mailshake/configuration'
9
+ require_relative 'mailshake/client'
10
+ require_relative 'mailshake/base'
11
+ require_relative 'mailshake/campaigns'
12
+ require_relative 'mailshake/recipients'
13
+ require_relative 'mailshake/activity'
14
+ require_relative 'mailshake/leads'
15
+ require_relative 'mailshake/team'
16
+ require_relative 'mailshake/senders'
17
+ require_relative 'mailshake/push'
18
+
19
+ module Mailshake
20
+ class << self
21
+ attr_accessor :configuration
22
+
23
+ def configure
24
+ self.configuration ||= Configuration.new
25
+ yield(configuration) if block_given?
26
+ end
27
+
28
+ def client
29
+ @client ||= Client.new(configuration)
30
+ end
31
+
32
+ def reset!
33
+ @client = nil
34
+ @configuration = nil
35
+ end
36
+ end
37
+ end
data/spec/examples.txt ADDED
@@ -0,0 +1,60 @@
1
+ example_id | status | run_time |
2
+ --------------------------------------------- | ------ | --------------- |
3
+ ./spec/mailshake/activity_spec.rb[1:1:1] | passed | 0.00026 seconds |
4
+ ./spec/mailshake/activity_spec.rb[1:1:2] | passed | 0.00036 seconds |
5
+ ./spec/mailshake/activity_spec.rb[1:2:1] | passed | 0.00044 seconds |
6
+ ./spec/mailshake/activity_spec.rb[1:3:1] | passed | 0.0004 seconds |
7
+ ./spec/mailshake/activity_spec.rb[1:4:1] | passed | 0.00051 seconds |
8
+ ./spec/mailshake/activity_spec.rb[1:5:1] | passed | 0.00041 seconds |
9
+ ./spec/mailshake/activity_spec.rb[1:6:1] | passed | 0.00034 seconds |
10
+ ./spec/mailshake/activity_spec.rb[1:7:1] | passed | 0.00039 seconds |
11
+ ./spec/mailshake/campaigns_spec.rb[1:1:1] | passed | 0.00037 seconds |
12
+ ./spec/mailshake/campaigns_spec.rb[1:1:2] | passed | 0.00034 seconds |
13
+ ./spec/mailshake/campaigns_spec.rb[1:2:1] | passed | 0.00033 seconds |
14
+ ./spec/mailshake/campaigns_spec.rb[1:3:1] | passed | 0.00036 seconds |
15
+ ./spec/mailshake/campaigns_spec.rb[1:4:1] | passed | 0.00029 seconds |
16
+ ./spec/mailshake/campaigns_spec.rb[1:5:1] | passed | 0.00029 seconds |
17
+ ./spec/mailshake/campaigns_spec.rb[1:6:1] | passed | 0.00033 seconds |
18
+ ./spec/mailshake/campaigns_spec.rb[1:7:1] | passed | 0.00033 seconds |
19
+ ./spec/mailshake/client_spec.rb[1:1:1] | passed | 0.00031 seconds |
20
+ ./spec/mailshake/client_spec.rb[1:1:2:1] | passed | 0.00054 seconds |
21
+ ./spec/mailshake/client_spec.rb[1:2:1] | passed | 0.00022 seconds |
22
+ ./spec/mailshake/client_spec.rb[1:2:2] | passed | 0.002 seconds |
23
+ ./spec/mailshake/client_spec.rb[1:2:3] | passed | 0.00041 seconds |
24
+ ./spec/mailshake/client_spec.rb[1:2:4] | passed | 0.00045 seconds |
25
+ ./spec/mailshake/client_spec.rb[1:3:1] | passed | 0.00039 seconds |
26
+ ./spec/mailshake/client_spec.rb[1:4:1] | passed | 0.00029 seconds |
27
+ ./spec/mailshake/client_spec.rb[1:5:1] | passed | 0.00038 seconds |
28
+ ./spec/mailshake/client_spec.rb[1:5:2] | passed | 0.00043 seconds |
29
+ ./spec/mailshake/client_spec.rb[1:5:3] | passed | 0.00038 seconds |
30
+ ./spec/mailshake/client_spec.rb[1:5:4] | passed | 0.00042 seconds |
31
+ ./spec/mailshake/client_spec.rb[1:5:5] | passed | 0.00064 seconds |
32
+ ./spec/mailshake/configuration_spec.rb[1:1:1] | passed | 0.00004 seconds |
33
+ ./spec/mailshake/configuration_spec.rb[1:1:2] | passed | 0.00004 seconds |
34
+ ./spec/mailshake/configuration_spec.rb[1:2:1] | passed | 0.00004 seconds |
35
+ ./spec/mailshake/configuration_spec.rb[1:2:2] | passed | 0.00004 seconds |
36
+ ./spec/mailshake/configuration_spec.rb[1:2:3] | passed | 0.00005 seconds |
37
+ ./spec/mailshake/configuration_spec.rb[1:3:1] | passed | 0.00005 seconds |
38
+ ./spec/mailshake/configuration_spec.rb[1:3:2] | passed | 0.00004 seconds |
39
+ ./spec/mailshake/leads_spec.rb[1:1:1] | passed | 0.00037 seconds |
40
+ ./spec/mailshake/leads_spec.rb[1:1:2] | passed | 0.00043 seconds |
41
+ ./spec/mailshake/leads_spec.rb[1:2:1] | passed | 0.00047 seconds |
42
+ ./spec/mailshake/leads_spec.rb[1:3:1] | passed | 0.00039 seconds |
43
+ ./spec/mailshake/leads_spec.rb[1:4:1] | passed | 0.00035 seconds |
44
+ ./spec/mailshake/leads_spec.rb[1:5:1] | passed | 0.00037 seconds |
45
+ ./spec/mailshake/leads_spec.rb[1:6:1] | passed | 0.00041 seconds |
46
+ ./spec/mailshake/push_spec.rb[1:1:1] | passed | 0.00183 seconds |
47
+ ./spec/mailshake/push_spec.rb[1:1:2] | passed | 0.00026 seconds |
48
+ ./spec/mailshake/push_spec.rb[1:2:1] | passed | 0.00032 seconds |
49
+ ./spec/mailshake/recipients_spec.rb[1:1:1] | passed | 0.00035 seconds |
50
+ ./spec/mailshake/recipients_spec.rb[1:2:1] | passed | 0.00074 seconds |
51
+ ./spec/mailshake/recipients_spec.rb[1:3:1] | passed | 0.0005 seconds |
52
+ ./spec/mailshake/recipients_spec.rb[1:3:2] | passed | 0.00049 seconds |
53
+ ./spec/mailshake/recipients_spec.rb[1:4:1] | passed | 0.00112 seconds |
54
+ ./spec/mailshake/recipients_spec.rb[1:5:1] | passed | 0.01614 seconds |
55
+ ./spec/mailshake/recipients_spec.rb[1:6:1] | passed | 0.00037 seconds |
56
+ ./spec/mailshake/recipients_spec.rb[1:7:1] | passed | 0.00035 seconds |
57
+ ./spec/mailshake/senders_spec.rb[1:1:1] | passed | 0.00027 seconds |
58
+ ./spec/mailshake/senders_spec.rb[1:1:2] | passed | 0.00054 seconds |
59
+ ./spec/mailshake/team_spec.rb[1:1:1] | passed | 0.0003 seconds |
60
+ ./spec/mailshake/team_spec.rb[1:1:2] | passed | 0.00039 seconds |
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Activity do
6
+ let(:activity) { described_class.new(Mailshake.client) }
7
+ let(:base_url) { "https://api.mailshake.com/2017-04-01" }
8
+
9
+ describe "#sent" do
10
+ it "lists sent messages" do
11
+ stub_request(:get, "#{base_url}/activity/sent")
12
+ .to_return(status: 200, body: { results: [] }.to_json,
13
+ headers: { "Content-Type" => "application/json" })
14
+
15
+ result = activity.sent
16
+ expect(result["results"]).to eq([])
17
+ end
18
+
19
+ it "passes campaign and pagination params" do
20
+ stub_request(:get, "#{base_url}/activity/sent")
21
+ .with(query: { campaignID: "1", perPage: "50" })
22
+ .to_return(status: 200, body: { results: [] }.to_json,
23
+ headers: { "Content-Type" => "application/json" })
24
+
25
+ activity.sent(campaign_id: "1", per_page: "50")
26
+ end
27
+ end
28
+
29
+ describe "#opens" do
30
+ it "lists opens" do
31
+ stub_request(:get, "#{base_url}/activity/opens")
32
+ .with(query: { campaignID: "1", excludeDuplicates: "true" })
33
+ .to_return(status: 200, body: { results: [] }.to_json,
34
+ headers: { "Content-Type" => "application/json" })
35
+
36
+ result = activity.opens(campaign_id: "1", exclude_duplicates: "true")
37
+ expect(result["results"]).to eq([])
38
+ end
39
+ end
40
+
41
+ describe "#clicks" do
42
+ it "lists clicks" do
43
+ stub_request(:get, "#{base_url}/activity/clicks")
44
+ .with(query: { campaignID: "1", matchUrl: "https://example.com" })
45
+ .to_return(status: 200, body: { results: [] }.to_json,
46
+ headers: { "Content-Type" => "application/json" })
47
+
48
+ activity.clicks(campaign_id: "1", match_url: "https://example.com")
49
+ end
50
+ end
51
+
52
+ describe "#replies" do
53
+ it "lists replies" do
54
+ stub_request(:get, "#{base_url}/activity/replies")
55
+ .with(query: { campaignID: "1", replyType: "reply" })
56
+ .to_return(status: 200, body: { results: [] }.to_json,
57
+ headers: { "Content-Type" => "application/json" })
58
+
59
+ activity.replies(campaign_id: "1", reply_type: "reply")
60
+ end
61
+ end
62
+
63
+ describe "#created_leads" do
64
+ it "lists created leads" do
65
+ stub_request(:get, "#{base_url}/activity/created-leads")
66
+ .with(query: { campaignID: "1", since: "2026-01-01" })
67
+ .to_return(status: 200, body: { results: [] }.to_json,
68
+ headers: { "Content-Type" => "application/json" })
69
+
70
+ activity.created_leads(campaign_id: "1", since: "2026-01-01")
71
+ end
72
+ end
73
+
74
+ describe "#lead_assignments" do
75
+ it "lists lead assignments" do
76
+ stub_request(:get, "#{base_url}/activity/lead-assignments")
77
+ .with(query: { campaignID: "1" })
78
+ .to_return(status: 200, body: { results: [] }.to_json,
79
+ headers: { "Content-Type" => "application/json" })
80
+
81
+ activity.lead_assignments(campaign_id: "1")
82
+ end
83
+ end
84
+
85
+ describe "#lead_status_changes" do
86
+ it "lists lead status changes" do
87
+ stub_request(:get, "#{base_url}/activity/lead-status-changes")
88
+ .with(query: { campaignID: "1", recipientEmailAddress: "john@example.com" })
89
+ .to_return(status: 200, body: { results: [] }.to_json,
90
+ headers: { "Content-Type" => "application/json" })
91
+
92
+ activity.lead_status_changes(campaign_id: "1", recipient_email_address: "john@example.com")
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Campaigns do
6
+ let(:campaigns) { described_class.new(Mailshake.client) }
7
+ let(:base_url) { "https://api.mailshake.com/2017-04-01" }
8
+
9
+ describe "#list" do
10
+ it "lists campaigns" do
11
+ stub_request(:get, "#{base_url}/campaigns/list")
12
+ .to_return(status: 200, body: { results: [] }.to_json,
13
+ headers: { "Content-Type" => "application/json" })
14
+
15
+ result = campaigns.list
16
+ expect(result["results"]).to eq([])
17
+ end
18
+
19
+ it "passes search and pagination params" do
20
+ stub_request(:get, "#{base_url}/campaigns/list")
21
+ .with(query: { search: "test", nextToken: "abc", perPage: "10" })
22
+ .to_return(status: 200, body: { results: [] }.to_json,
23
+ headers: { "Content-Type" => "application/json" })
24
+
25
+ campaigns.list(search: "test", next_token: "abc", per_page: "10")
26
+ end
27
+ end
28
+
29
+ describe "#get" do
30
+ it "gets a campaign by id" do
31
+ stub_request(:get, "#{base_url}/campaigns/get")
32
+ .with(query: { campaignID: "1" })
33
+ .to_return(status: 200, body: { id: 1, title: "Test Campaign" }.to_json,
34
+ headers: { "Content-Type" => "application/json" })
35
+
36
+ result = campaigns.get(campaign_id: "1")
37
+ expect(result["title"]).to eq("Test Campaign")
38
+ end
39
+ end
40
+
41
+ describe "#create" do
42
+ it "creates a campaign" do
43
+ stub_request(:post, "#{base_url}/campaigns/create")
44
+ .with(body: { title: "New Campaign", senderID: 5 }.to_json)
45
+ .to_return(status: 200, body: { id: 2, title: "New Campaign" }.to_json,
46
+ headers: { "Content-Type" => "application/json" })
47
+
48
+ result = campaigns.create(title: "New Campaign", sender_id: 5)
49
+ expect(result["title"]).to eq("New Campaign")
50
+ end
51
+ end
52
+
53
+ describe "#pause" do
54
+ it "pauses a campaign" do
55
+ stub_request(:post, "#{base_url}/campaigns/pause")
56
+ .with(body: { campaignID: 1 }.to_json)
57
+ .to_return(status: 200, body: {}.to_json,
58
+ headers: { "Content-Type" => "application/json" })
59
+
60
+ campaigns.pause(campaign_id: 1)
61
+ end
62
+ end
63
+
64
+ describe "#unpause" do
65
+ it "unpauses a campaign" do
66
+ stub_request(:post, "#{base_url}/campaigns/unpause")
67
+ .with(body: { campaignID: 1 }.to_json)
68
+ .to_return(status: 200, body: {}.to_json,
69
+ headers: { "Content-Type" => "application/json" })
70
+
71
+ campaigns.unpause(campaign_id: 1)
72
+ end
73
+ end
74
+
75
+ describe "#export" do
76
+ it "exports campaigns" do
77
+ stub_request(:post, "#{base_url}/campaigns/export")
78
+ .with(body: { campaignIDs: [1, 2], exportType: "csv", timezone: "US/Pacific" }.to_json)
79
+ .to_return(status: 200, body: { statusID: 42 }.to_json,
80
+ headers: { "Content-Type" => "application/json" })
81
+
82
+ result = campaigns.export(campaign_ids: [1, 2], export_type: "csv", timezone: "US/Pacific")
83
+ expect(result["statusID"]).to eq(42)
84
+ end
85
+ end
86
+
87
+ describe "#export_status" do
88
+ it "checks export status" do
89
+ stub_request(:get, "#{base_url}/campaigns/export-status")
90
+ .with(query: { statusID: "42" })
91
+ .to_return(status: 200, body: { isFinished: true, csvDownloadUrl: "https://example.com/file.csv" }.to_json,
92
+ headers: { "Content-Type" => "application/json" })
93
+
94
+ result = campaigns.export_status(status_id: "42")
95
+ expect(result["isFinished"]).to be true
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Client do
6
+ let(:client) { Mailshake.client }
7
+ let(:base_url) { "https://api.mailshake.com/2017-04-01" }
8
+ let(:expected_auth) { "Basic #{Base64.strict_encode64('test_api_key:')}" }
9
+
10
+ describe "#initialize" do
11
+ it "creates a client instance" do
12
+ expect(client).to be_a(described_class)
13
+ end
14
+
15
+ context "with missing credentials" do
16
+ it "raises a ConfigurationError" do
17
+ config = Mailshake::Configuration.new
18
+ expect { described_class.new(config) }.to raise_error(Mailshake::ConfigurationError)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe "#get" do
24
+ it "makes authenticated GET request" do
25
+ stub_request(:get, "#{base_url}/test")
26
+ .to_return(status: 200, body: { data: "ok" }.to_json,
27
+ headers: { "Content-Type" => "application/json" })
28
+
29
+ result = client.get("/test")
30
+ expect(result).to eq("data" => "ok")
31
+ end
32
+
33
+ it "sends Basic auth header with base64 encoded api key" do
34
+ stub_request(:get, "#{base_url}/test")
35
+ .to_return(status: 200, body: {}.to_json,
36
+ headers: { "Content-Type" => "application/json" })
37
+
38
+ client.get("/test")
39
+ expect(WebMock).to have_requested(:get, "#{base_url}/test")
40
+ .with(headers: { "Authorization" => expected_auth })
41
+ end
42
+
43
+ it "sends Accept: application/json header" do
44
+ stub_request(:get, "#{base_url}/test")
45
+ .to_return(status: 200, body: {}.to_json,
46
+ headers: { "Content-Type" => "application/json" })
47
+
48
+ client.get("/test")
49
+ expect(WebMock).to have_requested(:get, "#{base_url}/test")
50
+ .with(headers: { "Accept" => "application/json" })
51
+ end
52
+
53
+ it "passes query parameters" do
54
+ stub_request(:get, "#{base_url}/test")
55
+ .with(query: { campaignID: "1", perPage: "10" })
56
+ .to_return(status: 200, body: {}.to_json,
57
+ headers: { "Content-Type" => "application/json" })
58
+
59
+ client.get("/test", campaignID: "1", perPage: "10")
60
+ end
61
+ end
62
+
63
+ describe "#post" do
64
+ it "makes authenticated POST request with JSON body" do
65
+ stub_request(:post, "#{base_url}/test")
66
+ .with(body: { title: "Test" }.to_json,
67
+ headers: { "Content-Type" => "application/json" })
68
+ .to_return(status: 200, body: { id: 1 }.to_json,
69
+ headers: { "Content-Type" => "application/json" })
70
+
71
+ result = client.post("/test", title: "Test")
72
+ expect(result).to eq("id" => 1)
73
+ end
74
+ end
75
+
76
+ describe "#me" do
77
+ it "fetches the current user" do
78
+ stub_request(:get, "#{base_url}/me")
79
+ .to_return(status: 200, body: { teamID: 1, email: "test@example.com" }.to_json,
80
+ headers: { "Content-Type" => "application/json" })
81
+
82
+ result = client.me
83
+ expect(result["email"]).to eq("test@example.com")
84
+ end
85
+ end
86
+
87
+ describe "error handling" do
88
+ it "raises AuthenticationError on 401" do
89
+ stub_request(:get, "#{base_url}/expired")
90
+ .to_return(status: 401, body: "Unauthorized")
91
+
92
+ expect { client.get("/expired") }.to raise_error(Mailshake::AuthenticationError)
93
+ end
94
+
95
+ it "raises NotFoundError on 404" do
96
+ stub_request(:get, "#{base_url}/missing")
97
+ .to_return(status: 404, body: "Not Found")
98
+
99
+ expect { client.get("/missing") }.to raise_error(Mailshake::NotFoundError)
100
+ end
101
+
102
+ it "raises RateLimitError on 429 with retry-after" do
103
+ stub_request(:get, "#{base_url}/limited")
104
+ .to_return(status: 429, body: "Too Many Requests",
105
+ headers: { "retry-after" => "30" })
106
+
107
+ expect { client.get("/limited") }.to raise_error(Mailshake::RateLimitError) do |error|
108
+ expect(error.retry_after).to eq("30")
109
+ end
110
+ end
111
+
112
+ it "raises ValidationError on 400" do
113
+ stub_request(:post, "#{base_url}/bad")
114
+ .to_return(
115
+ status: 400,
116
+ body: { message: "Bad Request", errors: { "title" => ["is required"] } }.to_json,
117
+ headers: { "Content-Type" => "application/json" }
118
+ )
119
+
120
+ expect { client.post("/bad", {}) }.to raise_error(Mailshake::ValidationError) do |error|
121
+ expect(error.errors).to eq("title" => ["is required"])
122
+ end
123
+ end
124
+
125
+ it "raises APIError on 500" do
126
+ stub_request(:get, "#{base_url}/error")
127
+ .to_return(status: 500, body: "Internal Server Error")
128
+
129
+ expect { client.get("/error") }.to raise_error(Mailshake::APIError)
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Configuration do
6
+ describe "#initialize" do
7
+ it "sets default base_url" do
8
+ config = described_class.new
9
+ expect(config.base_url).to eq("https://api.mailshake.com/2017-04-01")
10
+ end
11
+
12
+ it "sets default timeout" do
13
+ config = described_class.new
14
+ expect(config.timeout).to eq(30)
15
+ end
16
+ end
17
+
18
+ describe "#valid?" do
19
+ it "returns true when api_key is set" do
20
+ config = described_class.new
21
+ config.api_key = "test_key"
22
+ expect(config.valid?).to be true
23
+ end
24
+
25
+ it "returns false when api_key is nil" do
26
+ config = described_class.new
27
+ expect(config.valid?).to be false
28
+ end
29
+
30
+ it "returns false when api_key is empty" do
31
+ config = described_class.new
32
+ config.api_key = ""
33
+ expect(config.valid?).to be false
34
+ end
35
+ end
36
+
37
+ describe "#missing_credentials" do
38
+ it "returns empty array when api_key is set" do
39
+ config = described_class.new
40
+ config.api_key = "test_key"
41
+ expect(config.missing_credentials).to eq([])
42
+ end
43
+
44
+ it "returns api_key when missing" do
45
+ config = described_class.new
46
+ expect(config.missing_credentials).to eq(["api_key"])
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Leads do
6
+ let(:leads) { described_class.new(Mailshake.client) }
7
+ let(:base_url) { "https://api.mailshake.com/2017-04-01" }
8
+
9
+ describe "#list" do
10
+ it "lists leads" do
11
+ stub_request(:get, "#{base_url}/leads/list")
12
+ .to_return(status: 200, body: { results: [] }.to_json,
13
+ headers: { "Content-Type" => "application/json" })
14
+
15
+ result = leads.list
16
+ expect(result["results"]).to eq([])
17
+ end
18
+
19
+ it "passes filter params" do
20
+ stub_request(:get, "#{base_url}/leads/list")
21
+ .with(query: { campaignID: "1", status: "open", perPage: "10" })
22
+ .to_return(status: 200, body: { results: [] }.to_json,
23
+ headers: { "Content-Type" => "application/json" })
24
+
25
+ leads.list(campaign_id: "1", status: "open", per_page: "10")
26
+ end
27
+ end
28
+
29
+ describe "#get" do
30
+ it "gets a lead by id" do
31
+ stub_request(:get, "#{base_url}/leads/get")
32
+ .with(query: { leadID: "42" })
33
+ .to_return(status: 200, body: { id: 42, status: "open" }.to_json,
34
+ headers: { "Content-Type" => "application/json" })
35
+
36
+ result = leads.get(lead_id: "42")
37
+ expect(result["status"]).to eq("open")
38
+ end
39
+ end
40
+
41
+ describe "#create" do
42
+ it "creates leads" do
43
+ stub_request(:post, "#{base_url}/leads/create")
44
+ .with(body: { campaignID: 1, emailAddresses: ["john@example.com"] }.to_json)
45
+ .to_return(status: 200, body: { results: [{ id: 1 }] }.to_json,
46
+ headers: { "Content-Type" => "application/json" })
47
+
48
+ result = leads.create(campaign_id: 1, email_addresses: ["john@example.com"])
49
+ expect(result["results"].length).to eq(1)
50
+ end
51
+ end
52
+
53
+ describe "#close" do
54
+ it "closes a lead" do
55
+ stub_request(:post, "#{base_url}/leads/close")
56
+ .with(body: { leadID: 42, status: "won" }.to_json)
57
+ .to_return(status: 200, body: {}.to_json,
58
+ headers: { "Content-Type" => "application/json" })
59
+
60
+ leads.close(lead_id: 42, status: "won")
61
+ end
62
+ end
63
+
64
+ describe "#ignore" do
65
+ it "ignores a lead" do
66
+ stub_request(:post, "#{base_url}/leads/ignore")
67
+ .with(body: { leadID: 42 }.to_json)
68
+ .to_return(status: 200, body: {}.to_json,
69
+ headers: { "Content-Type" => "application/json" })
70
+
71
+ leads.ignore(lead_id: 42)
72
+ end
73
+ end
74
+
75
+ describe "#reopen" do
76
+ it "reopens a lead" do
77
+ stub_request(:post, "#{base_url}/leads/reopen")
78
+ .with(body: { leadID: 42 }.to_json)
79
+ .to_return(status: 200, body: {}.to_json,
80
+ headers: { "Content-Type" => "application/json" })
81
+
82
+ leads.reopen(lead_id: 42)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Mailshake::Push do
6
+ let(:push) { described_class.new(Mailshake.client) }
7
+ let(:base_url) { "https://api.mailshake.com/2017-04-01" }
8
+
9
+ describe "#create" do
10
+ it "creates a push webhook" do
11
+ stub_request(:post, "#{base_url}/push/create")
12
+ .with(body: { targetUrl: "https://example.com/webhook", event: "reply" }.to_json)
13
+ .to_return(status: 200, body: { id: 1 }.to_json,
14
+ headers: { "Content-Type" => "application/json" })
15
+
16
+ result = push.create(target_url: "https://example.com/webhook", event: "reply")
17
+ expect(result["id"]).to eq(1)
18
+ end
19
+
20
+ it "passes filter param" do
21
+ stub_request(:post, "#{base_url}/push/create")
22
+ .with(body: { targetUrl: "https://example.com/webhook", event: "reply", filter: { campaignID: 1 } }.to_json)
23
+ .to_return(status: 200, body: { id: 1 }.to_json,
24
+ headers: { "Content-Type" => "application/json" })
25
+
26
+ push.create(target_url: "https://example.com/webhook", event: "reply", filter: { campaignID: 1 })
27
+ end
28
+ end
29
+
30
+ describe "#delete" do
31
+ it "deletes a push webhook" do
32
+ stub_request(:post, "#{base_url}/push/delete")
33
+ .with(body: { targetUrl: "https://example.com/webhook" }.to_json)
34
+ .to_return(status: 200, body: {}.to_json,
35
+ headers: { "Content-Type" => "application/json" })
36
+
37
+ push.delete(target_url: "https://example.com/webhook")
38
+ end
39
+ end
40
+ end