monolith-trello 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b0204cf895047636e5b51fb1fd4b43964cd2538616e5182515d5a21f5dbb0656
4
+ data.tar.gz: 664230200e2731e9316cde2653547e4994844e0e21b7b54a0f735137ad363686
5
+ SHA512:
6
+ metadata.gz: d03c59e497c074c4e6bd36f31c6534e0f7c381f5ebae343dbc8d87baa3e6b62adc8530a3326ac04f5e4a344df061280bb0871ed47fbd02546476d1bf0a92e91b
7
+ data.tar.gz: cd40098a7f168d66844c25ebc9deaf47550fce995796bdc65f57715a7cd665ce776cb84cc4078c99715f406a4fa65f79f9568baa68303d065590f1f4cee67e9c
data/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # Ruby Trello Lite
2
+
3
+ This is a learning project using this gem: [ruby-trello](https://github.com/jeremytregunna/ruby-trello).
4
+
5
+ The idea behind this project is to replicate some features using the examples in the gem's documentation.
6
+
7
+ ## Other ways to enhance this project
8
+ * Practice delegation (Forwardable)
9
+ * Practice ActiveModel
10
+
11
+ ## How to use this project
12
+
13
+ 1. Get your Trello API keys: [trello.com/api-key](https://trello.com/app-key/)
14
+ 2. Clone the project to your local repository
15
+ 3. In your repository, add `require './lib/trello'` in your "play" script. `run.rb` is provided as an example.
16
+ 4. Run your script
17
+
18
+ ## Features implemented so far:
19
+
20
+ 1. Configuration
21
+
22
+ ```
23
+ Trello.configure do |config|
24
+ config.consumer_key = TRELLO_CONSUMER_KEY
25
+ config.oauth_token = TRELLO_OAUTH_TOKEN
26
+ end
27
+ ```
28
+
29
+ 2. Member information
30
+
31
+ ```
32
+ bob = Trello::Member.find("bobtester")
33
+
34
+ # Print out his name
35
+ puts bob.full_name # "Bob Tester"
36
+
37
+ # Print his bio
38
+ puts bob.bio # A wonderfully delightful test user
39
+ ```
40
+
41
+ 3. List member boards (returns an array instead of ActiveModel:Associations)
42
+
43
+ ```
44
+ # Print boards
45
+
46
+ puts bob.boards
47
+
48
+ # Optional: limit the number of boards to view
49
+
50
+ puts bob.boards(10)
51
+
52
+ ```
53
+
54
+ 4. Find board (Custom to this gem)
55
+
56
+ ```
57
+
58
+ okrs_board = bob.find_board("okrs")
59
+
60
+ puts okrs_board
61
+
62
+ ```
63
+
64
+ 5. Get all the lists of that board and their names
65
+
66
+ ```
67
+
68
+ puts okrs_board.lists
69
+
70
+ # print all the list names of that board
71
+ okrs_board.lists.each do |list|
72
+ puts list.name
73
+ end
74
+
75
+ ```
76
+
77
+ 6. Get all the cards of a list and get all their names
78
+
79
+ ```
80
+
81
+ okrs_board.lists.first.cards.each do |card|
82
+ puts card.name
83
+ end
84
+ ```
85
+
86
+ ## TODO:
87
+
88
+ * Use active model so `bob.boards` returns a ActiveRecord-style associations object instead of just an array
89
+
90
+
91
+ ## Things I've Learned:
92
+
93
+ * How configuration through a block works (search for Trello.configure)
94
+ * How you can get standard libraries to work in local
95
+ (especially when autoload is used) ($LOAD_PATH.unshift 'lib'). This is true
96
+ in the case where you use the original library
97
+ * Metaprogramming hacks
98
+ * What I've noticed is that it's mainly a tool to add instance variables,
99
+ methods, and classes after it has been defined. It reminds me of
100
+ the way you can set methods in javascript after an object has been defined.
101
+ * Memoization: this is a way for you to easily define and reference instance variables without doing too many expensive method calls.
102
+
103
+ ## New techniques used:
104
+
105
+ * When consuming the JSON response of the API, assign it to an `@attributes` instance variable. In the future, you can do metaprogramming to automatically produce instance methods for this.
106
+ ```
107
+
108
+ def find(username)
109
+ url = "https://api.trello.com/1/members/#{username}?fields=all&#{credentials}"
110
+ @attributes = Trello.parse(url)
111
+ self
112
+ end
113
+
114
+ ```
115
+
@@ -0,0 +1,41 @@
1
+ module Trello
2
+ class Activity
3
+ attr_accessor :attributes
4
+
5
+ def initialize(attrs = {})
6
+ @attributes = attrs
7
+ end
8
+
9
+ def type
10
+ attributes[:type]
11
+ end
12
+
13
+ def name
14
+ attributes[:data][:card][:name]
15
+ end
16
+
17
+ def short_link
18
+ "https://trello.com/c/" + attributes[:data][:card][:shortLink]
19
+ end
20
+
21
+ def old_list
22
+ unless attributes[:data][:listBefore].nil?
23
+ attributes[:data][:listBefore][:name]
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def new_list
30
+ unless attributes[:data][:listAfter].nil?
31
+ attributes[:data][:listAfter][:name]
32
+ else
33
+ nil
34
+ end
35
+ end
36
+
37
+ def updated_at
38
+ Date.parse(attributes[:date]).strftime('%d/%m/%Y')
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,127 @@
1
+ module Trello
2
+ require 'json'
3
+
4
+ class Board
5
+ attr_accessor :id, :lists, :attributes
6
+
7
+ def initialize(id, attrs = {})
8
+ @id = id
9
+ @lists = []
10
+ @attributes = attrs
11
+ @board_url = "https://api.trello.com/1/boards/#{id}?fields=all&members=all&customFields=true"
12
+ @board_list_url = "https://api.trello.com/1/boards/#{id}/lists?cards=open&card_fields=name&filter=open&fields=all"
13
+ @members = []
14
+ @custom_fields = []
15
+ find(id)
16
+ end
17
+
18
+ def credentials
19
+ Trello.credentials
20
+ end
21
+
22
+ def find(id)
23
+ # puts "creating board #{id}"
24
+ @attributes = Trello.parse(@board_url + "&#{credentials}")
25
+ attributes[:members].each do |member|
26
+ member_obj = Member.new(member)
27
+ @members << member_obj
28
+ end
29
+ attributes[:customFields].each do |custom_field|
30
+ @custom_fields << CustomField.new(custom_field)
31
+ end
32
+ Trello.parse(@board_list_url + "&#{credentials}").each do |list_json|
33
+ list = List.new(list_json)
34
+ @lists << list
35
+ end
36
+ self
37
+ end
38
+
39
+ def find_list(name)
40
+ list_obj = nil
41
+ lists.each do |list|
42
+ list_obj = list if list.name == name
43
+ end
44
+ if list_obj.nil?
45
+ puts "List doesn't exist. Here are some list names."
46
+ lists.each do |list|
47
+ puts list.name
48
+ end
49
+ else
50
+ list_obj
51
+ end
52
+ end
53
+
54
+ def find_member(name)
55
+ @members.each do |member|
56
+ if name == member.full_name || name == member.username
57
+ return member
58
+ end
59
+ end
60
+ end
61
+
62
+ def check_created_cards_since(days_ago)
63
+ url = "https://api.trello.com/1/boards/#{id}/actions?#{credentials}"
64
+ activities = Trello.parse(url)
65
+ created_cards = []
66
+ activities.each do |activity|
67
+ if activity[:type] == "createCard" && Time.parse(activity[:date]) > days_ago
68
+ created_cards << Activity.new(activity)
69
+ end
70
+ end
71
+ created_cards
72
+ end
73
+
74
+ def lists
75
+ @lists
76
+ end
77
+
78
+ def name
79
+ attributes[:name]
80
+ end
81
+
82
+ def desc
83
+ attributes[:desc]
84
+ end
85
+
86
+ def url
87
+ attributes[:url]
88
+ end
89
+
90
+ def has_custom_fields?
91
+ url = "https://api.trello.com/1/boards/#{id}/plugins?filter=enabled&" + Trello.credentials
92
+ plugin_list = Trello.parse(url)
93
+ !plugin_list.select { |plugin| plugin[:name] == "Custom Fields"}.empty?
94
+ end
95
+
96
+ def custom_fields
97
+ @custom_fields
98
+ end
99
+
100
+ def enable_custom_fields
101
+ cf_id = "56d5e249a98895a9797bebb9"
102
+ url = "https://api.trello.com/1/boards/#{id}/boardPlugins?idPlugin=#{cf_id}&" + Trello.credentials
103
+
104
+ response = HTTParty.post(url, format: :plain)
105
+ JSON.parse(response, symbolize_names: true)
106
+ end
107
+
108
+ def create_work_units_field
109
+ url = "https://api.trello.com/1/customFields?" + Trello.credentials
110
+
111
+ wu_body = {
112
+ idModel: "#{id}",
113
+ modelType: "board",
114
+ name: "Work Units",
115
+ pos: "top",
116
+ type: "number",
117
+ display_cardFront: true
118
+ }
119
+
120
+ wu_headers = {
121
+ 'Content-Type': 'application/json'
122
+ }
123
+ response = HTTParty.post(url, body: wu_body, format: :plain)
124
+ JSON.parse(response, symbolize_names: true)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,93 @@
1
+ module Trello
2
+ class Card
3
+ attr_accessor :attributes, :url, :activities, :activities_url, :members
4
+
5
+ def initialize(attrs = {})
6
+ @attributes = attrs
7
+ @url = "https://api.trello.com/1/cards/#{attributes[:id]}?fields=all&members=true&member_fields=fullName%2Cusername&#{Trello.credentials}"
8
+ @activities_url = "https://api.trello.com/1/cards/#{attributes[:id]}/actions?limit=5&#{Trello.credentials}"
9
+ @card_json = nil
10
+ @activities = []
11
+ @members = []
12
+ end
13
+
14
+ def id
15
+ attributes[:id]
16
+ end
17
+
18
+ def name
19
+ attributes[:name]
20
+ end
21
+
22
+ def due
23
+ Time.parse(card_json[:due]).strftime("%d/%m/%Y")
24
+ end
25
+
26
+ def card_json
27
+ @card_json ||= Trello.parse(url)
28
+ end
29
+
30
+ def last_activity
31
+ Time.parse(card_json[:dateLastActivity]).strftime("%d/%m/%Y")
32
+ end
33
+
34
+ def due_complete
35
+ card_json[:dueComplete]
36
+ end
37
+
38
+ def short_link
39
+ card_json[:shortUrl]
40
+ end
41
+
42
+ def members
43
+ if @members.empty?
44
+ create_members
45
+ end
46
+ @members
47
+ end
48
+
49
+ def create_members
50
+ card_json[:members].each do |member|
51
+ @members << Member.new(member)
52
+ end
53
+ end
54
+
55
+ def status
56
+ unless due_complete
57
+ days = Date.parse(Time.now.strftime('%d/%m/%Y')) - Date.parse(due)
58
+ "Delayed by #{days.to_i} days"
59
+ else
60
+ "Done"
61
+ end
62
+ end
63
+
64
+ def work_units
65
+ url = "https://api.trello.com/1/cards/#{id}/customFieldItems?" + Trello.credentials
66
+ data = Trello.parse(url)
67
+ updated_data = data.select {|plugin| plugin[:value].keys.include?(:number)}
68
+ if updated_data.empty?
69
+ puts "kindly add work units"
70
+ else
71
+ updated_data[0][:value][:number].to_i
72
+ end
73
+ end
74
+
75
+ def activities_url
76
+ @activities_url
77
+ end
78
+
79
+ def activities(limit = 5)
80
+ unless @activities.empty? || limit != 5
81
+ @activities
82
+ else
83
+ Trello.parse(activities_url).each_with_index do |activity, idx|
84
+ _activity = Activity.new(activity)
85
+ if _activity.type == "updateCard" && !_activity.old_list.nil?
86
+ @activities << _activity
87
+ end
88
+ break if @activities.size == limit
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,16 @@
1
+ module Trello
2
+ class Client
3
+ def configure(&block)
4
+ return puts "No configuration details passed" unless block_given?
5
+ yield configuration
6
+ end
7
+
8
+ def configuration
9
+ @configuration ||= Configuration.new
10
+ end
11
+
12
+ def credentials
13
+ "key=#{configuration.consumer_key}&token=#{configuration.oauth_token}"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Trello
2
+ class Configuration
3
+ CONFIG_ATTRIBUTES = [
4
+ :consumer_key,
5
+ :consumer_secret,
6
+ :oauth_token,
7
+ :oauth_token_secret
8
+ ]
9
+
10
+ attr_accessor *CONFIG_ATTRIBUTES
11
+
12
+ def initialize(attrs = {})
13
+ @attributes = attrs
14
+ end
15
+
16
+ # this only works if you pass values through a block
17
+ def attributes=(attrs = {})
18
+ attrs.each { |key, value| instance_variable_set("@#{key}", value) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Trello
2
+ class CustomField
3
+ attr_accessor :attributes
4
+
5
+ def initialize(attrs = {})
6
+ @attributes = attrs
7
+ end
8
+
9
+ def id
10
+ attributes[:id]
11
+ end
12
+
13
+ def type
14
+ attributes[:type]
15
+ end
16
+
17
+ def name
18
+ attributes[:name]
19
+ end
20
+
21
+ def delete
22
+ url = "https://api.trello.com/1/customfields/#{id}?" + Trello.credentials
23
+ response = HTTParty.delete(url, format: :plain)
24
+ JSON.parse(response, symbolize_names: true)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ module Trello
2
+ class List
3
+ attr_accessor :attributes
4
+
5
+ def initialize(attrs = {})
6
+ @attributes = attrs
7
+ @cards = []
8
+ @attributes[:cards].each do |card|
9
+ card_obj = Card.new(card)
10
+ @cards << card_obj
11
+ end
12
+ end
13
+
14
+ def id
15
+ attributes[:id]
16
+ end
17
+
18
+ def name
19
+ attributes[:name]
20
+ end
21
+
22
+ def cards
23
+ @cards
24
+ end
25
+
26
+ def cards_by_member(username)
27
+ members_cards = []
28
+ @cards.each do |card|
29
+ member_in_card = card.members.select { |member| member.username == username }
30
+ next if member_in_card.empty?
31
+ members_cards << card
32
+ end
33
+ members_cards
34
+ end
35
+
36
+ def find_card(name = "")
37
+ card_obj = nil
38
+ cards.each do |card|
39
+ card_obj = card if card.name == name
40
+ end
41
+ if card_obj.nil?
42
+ puts "Card doesn't exist. Here are some card names."
43
+ cards.each do |card|
44
+ puts card.name
45
+ end
46
+ else
47
+ card_obj
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,74 @@
1
+ module Trello
2
+ class Member
3
+ attr_accessor :attributes
4
+
5
+ # to keep things pragmatic, @attributes holds the json
6
+ # a cool feature in the future is to use metaprogramming to automatically
7
+ # create instance methods, including an #instance_methods method
8
+ # to help the user better understand the API.
9
+ def initialize(attrs = {})
10
+ @attributes = attrs
11
+ @boards = []
12
+ @organizations = []
13
+ end
14
+
15
+ def credentials
16
+ Trello.credentials
17
+ end
18
+
19
+ def self.find(username)
20
+ @username = username
21
+ Trello.find_member(username)
22
+ end
23
+
24
+ def find(username)
25
+ url = "https://api.trello.com/1/members/#{username}?fields=all&organizations=members&organization_fields=all&#{credentials}"
26
+ @attributes = Trello.parse(url)
27
+ self
28
+ end
29
+
30
+ def full_name
31
+ attributes[:fullName]
32
+ end
33
+
34
+ def bio
35
+ attributes[:bio]
36
+ end
37
+
38
+ def username
39
+ @username ||= attributes[:username]
40
+ end
41
+
42
+ # just returns an array for now - would be cool to use activemodel
43
+ def boards(number = "none")
44
+ attributes[:idBoards].each_with_index do |id_board, idx|
45
+ number == "none" ? number = attributes[:idBoards].size : number
46
+ board_number = idx + 1
47
+ @boards << Board.new(id_board)
48
+ break if board_number == number
49
+ end
50
+ @boards
51
+ end
52
+
53
+ def find_board(name)
54
+ board = nil
55
+ attributes[:idBoards].each_with_index do |id_board, idx|
56
+ board_number = idx + 1
57
+ Board.new(id_board).name.downcase.include?(name.downcase) ? board = Board.new(id_board) : next
58
+ break
59
+ end
60
+ board
61
+ end
62
+
63
+ def organizations
64
+ attributes[:organizations].each do |org|
65
+ @organizations << Organization.new(org)
66
+ end
67
+ @organizations
68
+ end
69
+
70
+ def get_orgs_by_name(name)
71
+ organizations.select { |org| org.display_name.include?(name) }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,28 @@
1
+ module Trello
2
+ class Organization
3
+ attr_accessor :attributes
4
+
5
+ def initialize(attrs = {})
6
+ @attributes = attrs
7
+ @boards = []
8
+ end
9
+
10
+ def display_name
11
+ attributes[:displayName]
12
+ end
13
+
14
+ def name
15
+ attributes[:displayName]
16
+ end
17
+
18
+ def boards(limit = "all")
19
+ attributes[:idBoards].each_with_index do |board_id, idx|
20
+ @boards << Board.new(board_id)
21
+ unless limit == "all"
22
+ break if (idx + 1) == limit
23
+ end
24
+ end
25
+ @boards
26
+ end
27
+ end
28
+ end
data/lib/trello.rb ADDED
@@ -0,0 +1,49 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'httparty'
3
+ require 'pry-byebug'
4
+ require 'active_support/core_ext/integer/time'
5
+
6
+ module Trello
7
+ autoload :Card, 'trello-lite/card'
8
+ autoload :List, 'trello-lite/list'
9
+ autoload :Board, 'trello-lite/board'
10
+ autoload :Client, 'trello-lite/client'
11
+ autoload :Member, 'trello-lite/member'
12
+ autoload :Activity, 'trello-lite/activity'
13
+ autoload :Configuration, 'trello-lite/configuration'
14
+ autoload :Organization, 'trello-lite/organization'
15
+ autoload :CustomField, 'trello-lite/custom_field'
16
+
17
+ # parse url using httparty and return json
18
+ def self.parse(url)
19
+ response = HTTParty.get(url, format: :plain)
20
+ JSON.parse(response, symbolize_names: true)
21
+ end
22
+
23
+ # initialize a client in the environment
24
+ def self.client
25
+ @client ||= Client.new
26
+ end
27
+
28
+ # block for taking in some credentials
29
+ def self.configure(&block)
30
+ client.configure(&block)
31
+ end
32
+
33
+ # class methods in the Client object access the environment
34
+ # instance methods do the actual work
35
+ def self.credentials
36
+ client.credentials
37
+ end
38
+
39
+ # initialize a member in the environment
40
+ def self.member
41
+ @member ||= Member.new
42
+ end
43
+
44
+ # class methods in the Member object access the environment
45
+ # instance methods do the actual work
46
+ def self.find_member(username)
47
+ member.find(username)
48
+ end
49
+ end
@@ -0,0 +1,105 @@
1
+ require "rspec"
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18
+ RSpec.configure do |config|
19
+ # rspec-expectations config goes here. You can use an alternate
20
+ # assertion/expectation library such as wrong or the stdlib/minitest
21
+ # assertions if you prefer.
22
+ config.expect_with :rspec do |expectations|
23
+ # This option will default to `true` in RSpec 4. It makes the `description`
24
+ # and `failure_message` of custom matchers include text for helper methods
25
+ # defined using `chain`, e.g.:
26
+ # be_bigger_than(2).and_smaller_than(4).description
27
+ # # => "be bigger than 2 and smaller than 4"
28
+ # ...rather than:
29
+ # # => "be bigger than 2"
30
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
31
+ end
32
+
33
+ config.filter_run focus: true
34
+ config.run_all_when_everything_filtered = true
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
46
+ # have no way to turn it off -- the option exists only for backwards
47
+ # compatibility in RSpec 3). It causes shared context metadata to be
48
+ # inherited by the metadata hash of host groups and examples, rather than
49
+ # triggering implicit auto-inclusion in groups with matching metadata.
50
+ config.shared_context_metadata_behavior = :apply_to_host_groups
51
+
52
+ # The settings below are suggested to provide a good initial experience
53
+ # with RSpec, but feel free to customize to your heart's content.
54
+ =begin
55
+ # This allows you to limit a spec run to individual examples or groups
56
+ # you care about by tagging them with `:focus` metadata. When nothing
57
+ # is tagged with `:focus`, all examples get run. RSpec also provides
58
+ # aliases for `it`, `describe`, and `context` that include `:focus`
59
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
60
+ config.filter_run_when_matching :focus
61
+
62
+ # Allows RSpec to persist some state between runs in order to support
63
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
64
+ # you configure your source control system to ignore this file.
65
+ config.example_status_persistence_file_path = "spec/examples.txt"
66
+
67
+ # Limits the available syntax to the non-monkey patched syntax that is
68
+ # recommended. For more details, see:
69
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
70
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
71
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
72
+ config.disable_monkey_patching!
73
+
74
+ # This setting enables warnings. It's recommended, but in some cases may
75
+ # be too noisy due to issues in dependencies.
76
+ config.warnings = true
77
+
78
+ # Many RSpec users commonly either run the entire suite or an individual
79
+ # file, and it's useful to allow more verbose output when running an
80
+ # individual spec file.
81
+ if config.files_to_run.one?
82
+ # Use the documentation formatter for detailed output,
83
+ # unless a formatter has already been configured
84
+ # (e.g. via a command-line flag).
85
+ config.default_formatter = "doc"
86
+ end
87
+
88
+ # Print the 10 slowest examples and example groups at the
89
+ # end of the spec run, to help surface which specs are running
90
+ # particularly slow.
91
+ config.profile_examples = 10
92
+
93
+ # Run specs in random order to surface order dependencies. If you find an
94
+ # order dependency and want to debug it, you can fix the order by providing
95
+ # the seed, which is printed after each run.
96
+ # --seed 1234
97
+ config.order = :random
98
+
99
+ # Seed global randomization in this process using the `--seed` CLI option.
100
+ # Setting this allows you to use `--seed` to deterministically reproduce
101
+ # test failures related to randomization by passing the same `--seed` value
102
+ # as the one that triggered the failure.
103
+ Kernel.srand config.seed
104
+ =end
105
+ end
data/spec/user_spec.rb ADDED
@@ -0,0 +1,196 @@
1
+ require_relative 'spec_helper'
2
+ require 'dotenv/load'
3
+ require './lib/trello'
4
+
5
+ Trello.configure do |config|
6
+ config.consumer_key = ENV['CONSUMER_KEY']
7
+ config.oauth_token = ENV['OAUTH_TOKEN']
8
+ end
9
+
10
+ describe "Member" do
11
+ let(:kenn) {
12
+ Trello::Member.find("kennyfrc")
13
+ }
14
+
15
+ let(:board) {
16
+ kenn.find_board("okrs")
17
+ }
18
+
19
+ describe "has properties such as" do
20
+ it "can return the full name" do
21
+ expect(kenn.full_name).to eq "Kenn Costales"
22
+ end
23
+
24
+ it "can return the bio" do
25
+ expect(kenn.bio).to eq "Managing Director of Monolith Growth Consulting / [monolithgrowth.com](https://monolithgrowth.com)"
26
+ end
27
+
28
+ it "can return an array of boards" do
29
+ expect(kenn.boards(1).class).to eq Array
30
+ expect(kenn.boards(1)[0].class).to eq Trello::Board
31
+ end
32
+ end
33
+
34
+ describe "Board" do
35
+ it "can get the board name" do
36
+ expect(board.name).to eq "OKRs"
37
+ end
38
+
39
+ it "can get the lists of a board" do
40
+ expect(board.lists.class).to eq Array
41
+ expect(board.lists[0].class).to eq Trello::List
42
+ expect(board.lists[0].name.class).to eq String
43
+ end
44
+
45
+ # this will stop working if there's no card in the live boards that > 5 days old
46
+ # it "can get created cards from X" do
47
+ # expect(board.check_created_cards_since(5.days.ago).class).to eq Array
48
+ # expect(board.check_created_cards_since(5.days.ago)[0].class).to eq Trello::Activity
49
+ # expect(board.check_created_cards_since(5.days.ago)[0].name).to eq "something"
50
+ # expect(board.check_created_cards_since(5.days.ago)[0].short_link).to eq "https://trello.com/c/UPd7RKD4"
51
+ # expect(board.check_created_cards_since(5.days.ago)[0].updated_at).to eq "19/01/2020"
52
+ # end
53
+
54
+ ## Get members' cards for a board | https://developers.trello.com/reference#membersidboards
55
+
56
+ it "can get members' cards in a board" do
57
+ expect(board.find_list("Moving Out").cards_by_member("kennyfrc").class).to eq Array
58
+ expect(board.find_list("Moving Out").cards_by_member("kennyfrc")[0].class).to eq Trello::Card
59
+ expect(board.find_list("Moving Out").cards_by_member("kennyfrc")[0].name).to eq "MIDDLE cabinet - buy cr2032 batter for garmin awatch"
60
+ end
61
+
62
+ it "can check if it has the plugin" do
63
+ expect(board.has_custom_fields?).to eq true
64
+ end
65
+
66
+ it "has custom fields" do
67
+ expect(board.custom_fields[0].class).to eq Trello::CustomField
68
+ expect(board.custom_fields[0].name).to eq "Work Units"
69
+ end
70
+
71
+ it "its custom fields can be deleted" do
72
+ custom_fields = board.custom_fields
73
+ custom_fields.each do |custom_field|
74
+ custom_field.delete
75
+ end
76
+ updated_board = kenn.find_board("okrs")
77
+ expect(updated_board.custom_fields).to eq []
78
+ end
79
+
80
+ it "can create new custom fields" do
81
+ json = board.create_work_units_field
82
+ updated_board = kenn.find_board("okrs")
83
+ expect(updated_board.custom_fields[0].class).to eq Trello::CustomField
84
+ expect(updated_board.custom_fields[0].name).to eq "Work Units"
85
+ end
86
+
87
+ end
88
+
89
+ describe "List" do
90
+ let(:list) {
91
+ board.find_list("Moving Out")
92
+ }
93
+
94
+ it "get the list based on a name" do
95
+ expect(list.name).to eq "Moving Out"
96
+ expect(list.class).to eq Trello::List
97
+ end
98
+
99
+ it "get card name of a named list" do
100
+ expect(list.cards[0].name).to eq "MIDDLE cabinet - buy cr2032 batter for garmin awatch"
101
+ end
102
+ end
103
+
104
+ describe "Card" do
105
+ let(:list) {
106
+ board.find_list("Moving Out")
107
+ }
108
+
109
+ let(:card) {
110
+ list.find_card("MIDDLE cabinet - buy cr2032 batter for garmin awatch")
111
+ }
112
+
113
+ it "can find a card based on the name" do
114
+ expect(card.name).to eq "MIDDLE cabinet - buy cr2032 batter for garmin awatch"
115
+ end
116
+
117
+ it "has a due date" do
118
+ expect(card.due).to eq "17/08/2015"
119
+ end
120
+
121
+ it "has a last activity" do
122
+ expect(card.last_activity).to eq Date.parse(Time.now.strftime('%d/%m/%Y')).strftime('%d/%m/%Y')
123
+ end
124
+
125
+ it "has a due complete" do
126
+ expect(card.due_complete).to eq false
127
+ end
128
+
129
+ it "contains a short url" do
130
+ expect(card.short_link).to eq "https://trello.com/c/NLHqoq08"
131
+ end
132
+
133
+ it "days ahead or before due" do
134
+ expect(card.status).to eq "Delayed by #{(Date.parse(Time.now.strftime('%d/%m/%Y')) - Date.parse("17/08/2015")).to_i} days"
135
+ end
136
+
137
+ it "has activities" do
138
+ expect(card.activities.class).to eq Array
139
+ expect(card.activities[0].class).to eq Trello::Activity
140
+ expect(card.activities[0].type).to eq "updateCard"
141
+ expect(card.activities[0].old_list).to eq "miCab MKT & partnerships"
142
+ expect(card.activities[0].new_list).to eq "Moving Out"
143
+ expect(card.activities[0].updated_at).to eq "18/01/2020"
144
+ end
145
+
146
+ it "has members" do
147
+ expect(card.members.class).to eq Array
148
+ expect(card.members[0].class).to eq Trello::Member
149
+ end
150
+
151
+ it "has work units" do
152
+ expect(card.work_units).to eq nil
153
+ end
154
+ end
155
+
156
+ describe "Organization" do
157
+ it "can get a list of organizations" do
158
+ expect(kenn.organizations[0].class).to eq Trello::Organization
159
+ expect(kenn.organizations.class).to eq Array
160
+ end
161
+
162
+ it "can filter organizations based on name" do
163
+ expect(kenn.get_orgs_by_name("MGV Operations")[0].class).to eq Trello::Organization
164
+ expect(kenn.get_orgs_by_name("MGV Operations").class).to eq Array
165
+ end
166
+
167
+ it "has board ids" do
168
+ expect(kenn.get_orgs_by_name("MGV Operations").map {|org| org.boards(1)}[0].class).to eq Array
169
+ expect(kenn.get_orgs_by_name("MGV Operations").map {|org| org.boards(1)}[0][0].class).to eq Trello::Board
170
+ end
171
+ end
172
+ end
173
+
174
+
175
+ # megatracker features
176
+ ## DONE get cards from the "Backlog", "Doing", "Done", "Sprint" cards
177
+ ## DONE what card names are in the list
178
+ ## DONE check if the task has been made
179
+ ## DONE are we on or off the due date
180
+ ## DONE check the date of last activity of that card
181
+ ## DONE when is the due date of the card
182
+ ## DONE - card changes only - check activities | https://developers.trello.com/reference#cardsidactions
183
+ ## DONE check if the task was moved to another list
184
+ ## DONE get members in a card
185
+ ## DONE LIST | check if we have any tasks created this week | https://developers.trello.com/reference#listsidactions
186
+ ## DONE LIST? | check the create date of the card | https://developers.trello.com/reference#listsidactions
187
+ ## DONE Get members' cards for a board | https://developers.trello.com/reference#membersidboards
188
+ ## DONE Get members' cards for a board and a specific list | https://developers.trello.com/reference#membersidcards
189
+ ## DONE Organizations
190
+ ## Post work units for a card
191
+ ## Get work units for a card
192
+
193
+ # check rate limit
194
+ ## 300 requests per 10 seconds
195
+
196
+
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monolith-trello
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kenn Costales
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A wrapper around the trello.com API, built around Monolith's scrum use
56
+ cases.
57
+ email: marketing@askmonolith.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files:
61
+ - README.md
62
+ files:
63
+ - README.md
64
+ - lib/trello-lite/activity.rb
65
+ - lib/trello-lite/board.rb
66
+ - lib/trello-lite/card.rb
67
+ - lib/trello-lite/client.rb
68
+ - lib/trello-lite/configuration.rb
69
+ - lib/trello-lite/custom_field.rb
70
+ - lib/trello-lite/list.rb
71
+ - lib/trello-lite/member.rb
72
+ - lib/trello-lite/organization.rb
73
+ - lib/trello.rb
74
+ - spec/spec_helper.rb
75
+ - spec/user_spec.rb
76
+ homepage: https://github.com/kennyfrc/ruby-trello-lite
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options:
82
+ - "--charset=UTF-8"
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2.1.0
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.0.3
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: A wrapper around the trello.com API, built around Monolith's scrum use cases.
100
+ test_files:
101
+ - spec/spec_helper.rb
102
+ - spec/user_spec.rb