monolith-trello 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.
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