nt_models 0.1.1

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
+ SHA1:
3
+ metadata.gz: 67ab343ca340b88ae74a308e0b48defb99d18eeb
4
+ data.tar.gz: 719e23d3548c5f1f70614293afc8b03de0d68ce1
5
+ SHA512:
6
+ metadata.gz: 8cc798e18e5d20c28f463a2e04fb258a5a4da3ed0c3efffeb3e88780aa1571d6677a76fc6021b405761d57aaef80270bc54f3f4bad951ba5a450a6faae9d9ba6
7
+ data.tar.gz: 51a970a183e3eb3c59a38a01fd06a9dffbf160a130a40e6409d74848f382753707136b944f16aabb8157dfab704ba34ebe8c0b5a5997010d5e5792c8003a5944
@@ -0,0 +1,10 @@
1
+ # Initializes the db's User table
2
+ class CreateUserTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :users do |t|
5
+ t.string :name
6
+ t.string :handle
7
+ t.string :password_digest
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # Initializes the db's Tweet table
2
+ class CreateTweetTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :tweets do |t|
5
+ t.string :body
6
+ t.datetime :created_on
7
+ t.integer :author_id
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # Initializes db's Tweet Tag table
2
+ class CreateTweetTagTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :tweet_tags do |t|
5
+ t.integer :hashtag_id
6
+ t.integer :tweet_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ # Initializes the db's Hashtag table
2
+ class CreateHashtagTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :hashtags do |t|
5
+ t.text :name
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ # Initializes db's Timeline Piece table
2
+ class CreateTimelinePieceTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :timeline_pieces do |t|
5
+ t.integer :timeline_owner_id
6
+ t.integer :tweet_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # Initializes the db's Mention table
2
+ class CreateMentionTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :mentions do |t|
5
+ t.integer :tweet_id
6
+ t.integer :mentioned_user_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # Initializes db's Follow table
2
+ class CreateFollowTable < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :follows do |t|
5
+ t.integer :follower_id
6
+ t.integer :followee_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ Dir["#{__dir__}/models/*.rb"].each { |file| require file }
data/db/schema.rb ADDED
@@ -0,0 +1,54 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(version: 2019_02_26_212737) do
14
+
15
+ # These are extensions that must be enabled in order to support this database
16
+ enable_extension "plpgsql"
17
+
18
+ create_table "follows", force: :cascade do |t|
19
+ t.integer "follower_id"
20
+ t.integer "followee_id"
21
+ end
22
+
23
+ create_table "hashtags", force: :cascade do |t|
24
+ t.text "name"
25
+ end
26
+
27
+ create_table "mentions", force: :cascade do |t|
28
+ t.integer "tweet_id"
29
+ t.integer "mentioned_user_id"
30
+ end
31
+
32
+ create_table "timeline_pieces", force: :cascade do |t|
33
+ t.integer "timeline_owner_id"
34
+ t.integer "tweet_id"
35
+ end
36
+
37
+ create_table "tweet_tags", force: :cascade do |t|
38
+ t.integer "hashtag_id"
39
+ t.integer "tweet_id"
40
+ end
41
+
42
+ create_table "tweets", force: :cascade do |t|
43
+ t.string "body"
44
+ t.datetime "created_on"
45
+ t.integer "author_id"
46
+ end
47
+
48
+ create_table "users", force: :cascade do |t|
49
+ t.string "name"
50
+ t.string "handle"
51
+ t.string "password_digest"
52
+ end
53
+
54
+ end
@@ -0,0 +1,11 @@
1
+ # Represents the db's Follow table
2
+ class Follow < ActiveRecord::Base
3
+ belongs_to :follower, class_name: 'User'
4
+ belongs_to :followee, class_name: 'User'
5
+
6
+ # No two follows should have the same follower and followee
7
+ validates_uniqueness_of :follower_id, scope: %i[followee_id]
8
+
9
+ # Follower != Followee (user can't follow themselves)
10
+ validates :follower_id, exclusion: { in: ->(follow) { [follow.followee_id] } }
11
+ end
@@ -0,0 +1,5 @@
1
+ # Represents the db's Hashtag table
2
+ class Hashtag < ActiveRecord::Base
3
+ has_many :tweet_tags
4
+ has_many :tweets, through: :tweet_tags
5
+ end
@@ -0,0 +1,5 @@
1
+ # Represents the db's Mention table
2
+ class Mention < ActiveRecord::Base
3
+ belongs_to :mentioned_user, class_name: 'User'
4
+ belongs_to :tweet
5
+ end
@@ -0,0 +1,5 @@
1
+ # Represents the db's Timeline_piece table
2
+ class TimelinePiece < ActiveRecord::Base
3
+ belongs_to :timeline_owner
4
+ belongs_to :tweet
5
+ end
@@ -0,0 +1,10 @@
1
+ # Represents the db's Tweet table
2
+ class Tweet < ActiveRecord::Base
3
+ belongs_to :author, class_name: 'User', foreign_key: :author_id
4
+ has_many :tweet_tags
5
+ has_many :hashtags, through: :tweet_tags
6
+ has_many :mentions
7
+ has_many :mentioned_users, through: :mentions
8
+ has_many :timeline_pieces
9
+ has_many :timeline_users, through: :timeline_pieces, source: :timeline_owner
10
+ end
@@ -0,0 +1,5 @@
1
+ # Represents the db's Tweet_Tag table
2
+ class TweetTag < ActiveRecord::Base
3
+ belongs_to :tweet
4
+ belongs_to :hashtag
5
+ end
@@ -0,0 +1,20 @@
1
+ # Represents the db's User table
2
+ class User < ActiveRecord::Base
3
+ has_secure_password
4
+ validates :handle, presence: true, uniqueness: true
5
+
6
+ has_many :follows_from_me, class_name: 'Follow', foreign_key: :follower_id
7
+ has_many :followees, through: :follows_from_me
8
+
9
+ # Followers are people who follow this user
10
+ has_many :follows_to_me, class_name: 'Follow', foreign_key: :followee_id
11
+ has_many :followers, through: :follows_to_me
12
+
13
+ has_many :tweets, foreign_key: :author_id
14
+ has_many :tweet_tags, through: :tweets
15
+ has_many :timeline_pieces, foreign_key: :timeline_owner_id
16
+ has_many :timeline_tweets, through: :timeline_pieces, source: :tweet
17
+ has_many :mentions, foreign_key: :mentioned_user_id
18
+ has_many :mentioned_tweets, through: :mentions, source: :tweet
19
+
20
+ end
data/lib/nt_models.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'sinatra/activerecord'
2
+ require 'active_record'
3
+
4
+ unless Sinatra::Base.production?
5
+ require 'pry-byebug'
6
+ end
7
+
8
+ Dir["#{__dir__}/models/*.rb"].each { |file| require file }
@@ -0,0 +1,60 @@
1
+ def follow(follower, followee)
2
+ Follow.create(follower: follower, followee: followee)
3
+ end
4
+
5
+ describe 'follows' do
6
+ before do
7
+ follow(@brad, @ari)
8
+ end
9
+
10
+ it 'can tell how many people are following Ari' do
11
+ @ari.followers.count.must_equal 1
12
+ end
13
+
14
+ it 'can tell how many people Brad is following' do
15
+ @brad.followees.count.must_equal 1
16
+ end
17
+
18
+ it 'can handle multiple followers' do
19
+ [@yang, @pito].each { |u| follow(u, @ari) }
20
+ @ari.followers.count.must_equal 3
21
+ [@brad, @yang, @pito].each { |u| u.followees.count.must_equal 1 }
22
+ end
23
+
24
+ it 'can handle multiple followees' do
25
+ [@yang, @pito].each { |u| follow(@brad, u) }
26
+ @brad.followees.count.must_equal 3
27
+ [@ari, @yang, @pito].each { |u| u.followers.count.must_equal 1 }
28
+ end
29
+
30
+ it 'will not let Brad follow Ari twice' do
31
+ f = Follow.new(follower_id: @brad.id, followee_id: @ari.id)
32
+ f.save.must_equal false
33
+ end
34
+
35
+ it 'will not let Ari follow himself' do
36
+ f = Follow.new(follower_id: @ari.id, followee_id: @ari.id)
37
+ f.save.must_equal false
38
+ end
39
+
40
+ it 'will let Ari follow Brad even though Brad already follows Ari' do
41
+ f = Follow.new(follower_id: @ari.id, followee_id: @brad.id)
42
+ f.save.must_equal true
43
+ @ari.followees.count.must_equal 1
44
+ @brad.followers.count.must_equal 1
45
+ end
46
+
47
+ it 'will let follows be created from the follower' do
48
+ @ari.followees << @brad
49
+ Follow.count.must_equal 2
50
+ @ari.followees.count.must_equal 1
51
+ @brad.followers.count.must_equal 1
52
+ end
53
+
54
+ it 'will let follows be created from the followee' do
55
+ @brad.followers << @ari
56
+ Follow.count.must_equal 2
57
+ @ari.followees.count.must_equal 1
58
+ @brad.followers.count.must_equal 1
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ # This file is a DRY way to set all of the requirements
2
+ # that our tests will need, as well as a before statement
3
+ # that purges the database and creates fixtures before every test
4
+
5
+ ENV['APP_ENV'] = 'test'
6
+ require 'simplecov'
7
+ SimpleCov.start
8
+ require 'minitest/autorun'
9
+ require 'nt_models'
10
+
11
+ # Define file path pattern for identifying test files:
12
+ test_pattern = '*_test.rb'
13
+
14
+ describe 'NanoTwitter' do
15
+ before do
16
+ ActiveRecord::Base.subclasses.each(&:delete_all)
17
+ names = %w[ari brad yang pito]
18
+ users = names.map { |s| User.create(name: s.capitalize, handle: "@#{s}", password: "#{s}123") }
19
+ @ari, @brad, @yang, @pito = users
20
+ end
21
+
22
+ Dir["#{__dir__}/#{test_pattern}"].each { |file| require file }
23
+ end
@@ -0,0 +1,16 @@
1
+ describe 'tweets' do
2
+
3
+ before do
4
+ @tweet = Tweet.create(author_id: @ari.id, body: 'Scalability!', created_on: DateTime.now)
5
+ end
6
+
7
+ it 'can create a tweet' do
8
+ Tweet.count.must_equal 1
9
+ end
10
+
11
+ it 'can associate tweets with authors' do
12
+ @ari.tweets.count.must_equal 1
13
+ @tweet.author.must_equal @ari
14
+ end
15
+
16
+ end
data/test/user_test.rb ADDED
@@ -0,0 +1,30 @@
1
+ describe 'User model' do
2
+
3
+ it 'has 4 users' do
4
+ User.count.must_equal 4
5
+ end
6
+
7
+ it 'can destroy a user' do
8
+ @ari.destroy
9
+ User.count.must_equal 3
10
+ end
11
+
12
+ it 'requires a handle and a password' do
13
+ chi = User.new(name: 'Chi', password: 'chi123')
14
+ chi.save.must_equal false
15
+
16
+ chi = User.new(name: 'Chi', handle: '@chi')
17
+ chi.save.must_equal false
18
+ end
19
+
20
+ it 'requires a unique handle' do
21
+ fake_ari = User.new(name: 'Ari', handle: @ari.handle, password: 'identitytheftisnotajoke')
22
+ fake_ari.save.must_equal false
23
+ end
24
+
25
+ it 'can authenticate a user' do
26
+ @ari.authenticate('ari123').must_equal @ari
27
+ @ari.authenticate('iforgetmypassword').must_equal false
28
+ end
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nt_models
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ari Carr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: sinatra
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: sinatra-activerecord
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
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pg
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bcrypt
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description:
112
+ email: acarr@brandeis.edu
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - "./db/migrate/20190225192049_create_user_table.rb"
118
+ - "./db/migrate/20190225201314_create_tweet_table.rb"
119
+ - "./db/migrate/20190226212517_create_tweet_tag_table.rb"
120
+ - "./db/migrate/20190226212626_create_hashtag_table.rb"
121
+ - "./db/migrate/20190226212645_create_timeline_piece_table.rb"
122
+ - "./db/migrate/20190226212658_create_mention_table.rb"
123
+ - "./db/migrate/20190226212737_create_follow_table.rb"
124
+ - "./db/migrate/nt_models.rb"
125
+ - "./db/schema.rb"
126
+ - "./lib/models/follow.rb"
127
+ - "./lib/models/hashtag.rb"
128
+ - "./lib/models/mention.rb"
129
+ - "./lib/models/timeline_piece.rb"
130
+ - "./lib/models/tweet.rb"
131
+ - "./lib/models/tweet_tag.rb"
132
+ - "./lib/models/user.rb"
133
+ - "./lib/nt_models.rb"
134
+ - "./test/follow_test.rb"
135
+ - "./test/test_helper.rb"
136
+ - "./test/tweet_test.rb"
137
+ - "./test/user_test.rb"
138
+ homepage:
139
+ licenses: []
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.5.2
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Models for COSI 105B project
161
+ test_files: []