unsakini 0.0.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.
Files changed (184) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +34 -0
  5. data/angular/README.md +31 -0
  6. data/angular/angular-cli.json +59 -0
  7. data/angular/karma.conf.js +45 -0
  8. data/angular/package.json +49 -0
  9. data/angular/protractor.conf.js +32 -0
  10. data/angular/src/app/app.component.css +0 -0
  11. data/angular/src/app/app.component.html +4 -0
  12. data/angular/src/app/app.component.spec.ts +47 -0
  13. data/angular/src/app/app.component.ts +10 -0
  14. data/angular/src/app/app.module.ts +29 -0
  15. data/angular/src/app/app.routes.module.ts +29 -0
  16. data/angular/src/app/index.ts +2 -0
  17. data/angular/src/app/registration/registration.component.css +0 -0
  18. data/angular/src/app/registration/registration.component.html +14 -0
  19. data/angular/src/app/registration/registration.component.spec.ts +157 -0
  20. data/angular/src/app/registration/registration.component.ts +42 -0
  21. data/angular/src/environments/environment.prod.ts +3 -0
  22. data/angular/src/environments/environment.ts +8 -0
  23. data/angular/src/favicon.ico +0 -0
  24. data/angular/src/index.html +14 -0
  25. data/angular/src/main.ts +12 -0
  26. data/angular/src/polyfills.ts +19 -0
  27. data/angular/src/styles.css +1 -0
  28. data/angular/src/test.ts +31 -0
  29. data/angular/src/tsconfig.json +18 -0
  30. data/angular/src/typings.d.ts +2 -0
  31. data/angular/tslint.json +114 -0
  32. data/angular/typings.json +4 -0
  33. data/app/controllers/api/boards_controller.rb +67 -0
  34. data/app/controllers/api/comments_controller.rb +51 -0
  35. data/app/controllers/api/posts_controller.rb +58 -0
  36. data/app/controllers/api/share_board_controller.rb +118 -0
  37. data/app/controllers/api/users_controller.rb +27 -0
  38. data/app/controllers/application_controller.rb +5 -0
  39. data/app/controllers/concerns/board_owner_controller_concern.rb +38 -0
  40. data/app/controllers/concerns/comment_owner_controller_concern.rb +33 -0
  41. data/app/controllers/concerns/logged_in_controller_concern.rb +21 -0
  42. data/app/controllers/concerns/post_owner_controller_concern.rb +36 -0
  43. data/app/controllers/concerns/serializer_controller_concern.rb +11 -0
  44. data/app/controllers/user_token_controller.rb +2 -0
  45. data/app/controllers/web_base_controller.rb +11 -0
  46. data/app/models/application_record.rb +5 -0
  47. data/app/models/board.rb +14 -0
  48. data/app/models/comment.rb +9 -0
  49. data/app/models/concerns/encryptable_model_concern.rb +96 -0
  50. data/app/models/post.rb +12 -0
  51. data/app/models/user.rb +6 -0
  52. data/app/models/user_board.rb +71 -0
  53. data/app/serializers/board_serializer.rb +5 -0
  54. data/app/serializers/comment_serializer.rb +10 -0
  55. data/app/serializers/post_serializer.rb +23 -0
  56. data/app/serializers/user_board_serializer.rb +10 -0
  57. data/app/serializers/user_serializer.rb +6 -0
  58. data/config/initializers/unsakini.rb +4 -0
  59. data/config/routes.rb +22 -0
  60. data/db/migrate/20161116114222_create_boards.rb +9 -0
  61. data/db/migrate/20161116200034_create_user_boards.rb +11 -0
  62. data/db/migrate/20161118031023_create_posts.rb +12 -0
  63. data/db/migrate/20161118100454_create_comments.rb +11 -0
  64. data/db/migrate/20161118221508_add_encrypted_password_to_user_board.rb +5 -0
  65. data/db/migrate/20161122211105_create_users.rb +12 -0
  66. data/lib/generators/unsakini/angular/USAGE +8 -0
  67. data/lib/generators/unsakini/angular/angular_generator.rb +7 -0
  68. data/lib/generators/unsakini/config/USAGE +8 -0
  69. data/lib/generators/unsakini/config/config_generator.rb +7 -0
  70. data/lib/generators/unsakini/config/templates/unsakini.rb +4 -0
  71. data/lib/tasks/unsakini_tasks.rake +33 -0
  72. data/lib/unsakini/engine.rb +30 -0
  73. data/lib/unsakini/version.rb +3 -0
  74. data/lib/unsakini.rb +5 -0
  75. data/spec/concerns/models/encryptable_concern.rb +40 -0
  76. data/spec/dummy/Rakefile +6 -0
  77. data/spec/dummy/angular/README.md +31 -0
  78. data/spec/dummy/angular/angular-cli.json +59 -0
  79. data/spec/dummy/angular/e2e/app.e2e-spec.ts +14 -0
  80. data/spec/dummy/angular/e2e/app.po.ts +11 -0
  81. data/spec/dummy/angular/e2e/signup.e2e-spec.ts +28 -0
  82. data/spec/dummy/angular/e2e/signup.po.ts +31 -0
  83. data/spec/dummy/angular/e2e/tsconfig.json +16 -0
  84. data/spec/dummy/angular/karma.conf.js +45 -0
  85. data/spec/dummy/angular/package.json +50 -0
  86. data/spec/dummy/angular/protractor.conf.js +32 -0
  87. data/spec/dummy/angular/src/app/app.component.css +0 -0
  88. data/spec/dummy/angular/src/app/app.component.html +4 -0
  89. data/spec/dummy/angular/src/app/app.component.spec.ts +47 -0
  90. data/spec/dummy/angular/src/app/app.component.ts +10 -0
  91. data/spec/dummy/angular/src/app/app.module.ts +29 -0
  92. data/spec/dummy/angular/src/app/app.routes.module.ts +29 -0
  93. data/spec/dummy/angular/src/app/index.ts +2 -0
  94. data/spec/dummy/angular/src/app/registration/registration.component.css +0 -0
  95. data/spec/dummy/angular/src/app/registration/registration.component.html +14 -0
  96. data/spec/dummy/angular/src/app/registration/registration.component.spec.ts +157 -0
  97. data/spec/dummy/angular/src/app/registration/registration.component.ts +42 -0
  98. data/spec/dummy/angular/src/environments/environment.prod.ts +3 -0
  99. data/spec/dummy/angular/src/environments/environment.ts +8 -0
  100. data/spec/dummy/angular/src/favicon.ico +0 -0
  101. data/spec/dummy/angular/src/index.html +14 -0
  102. data/spec/dummy/angular/src/main.ts +12 -0
  103. data/spec/dummy/angular/src/polyfills.ts +19 -0
  104. data/spec/dummy/angular/src/styles.css +1 -0
  105. data/spec/dummy/angular/src/test.ts +31 -0
  106. data/spec/dummy/angular/src/tsconfig.json +18 -0
  107. data/spec/dummy/angular/src/typings.d.ts +2 -0
  108. data/spec/dummy/angular/tslint.json +114 -0
  109. data/spec/dummy/angular/typings.json +4 -0
  110. data/spec/dummy/app/assets/config/manifest.js +3 -0
  111. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  112. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  113. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  114. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  115. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  116. data/spec/dummy/app/jobs/application_job.rb +2 -0
  117. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  118. data/spec/dummy/app/models/application_record.rb +3 -0
  119. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  120. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  121. data/spec/dummy/bin/bundle +3 -0
  122. data/spec/dummy/bin/rails +4 -0
  123. data/spec/dummy/bin/rake +4 -0
  124. data/spec/dummy/bin/setup +34 -0
  125. data/spec/dummy/bin/update +29 -0
  126. data/spec/dummy/config/application.rb +22 -0
  127. data/spec/dummy/config/boot.rb +5 -0
  128. data/spec/dummy/config/cable.yml +9 -0
  129. data/spec/dummy/config/crypto.yml +7 -0
  130. data/spec/dummy/config/database.yml +25 -0
  131. data/spec/dummy/config/environment.rb +5 -0
  132. data/spec/dummy/config/environments/development.rb +47 -0
  133. data/spec/dummy/config/environments/production.rb +78 -0
  134. data/spec/dummy/config/environments/test.rb +42 -0
  135. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
  136. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  137. data/spec/dummy/config/initializers/cors.rb +16 -0
  138. data/spec/dummy/config/initializers/inflections.rb +16 -0
  139. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  140. data/spec/dummy/config/initializers/new_framework_defaults.rb +18 -0
  141. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  142. data/spec/dummy/config/locales/en.yml +23 -0
  143. data/spec/dummy/config/puma.rb +47 -0
  144. data/spec/dummy/config/routes.rb +3 -0
  145. data/spec/dummy/config/secrets.yml +22 -0
  146. data/spec/dummy/config/spring.rb +6 -0
  147. data/spec/dummy/config.ru +5 -0
  148. data/spec/dummy/db/development.sqlite3 +0 -0
  149. data/spec/dummy/db/schema.rb +56 -0
  150. data/spec/dummy/db/test.sqlite3 +0 -0
  151. data/spec/dummy/public/app/favicon.ico +0 -0
  152. data/spec/dummy/public/app/index.html +14 -0
  153. data/spec/dummy/public/app/inline.bundle.js +139 -0
  154. data/spec/dummy/public/app/inline.map +1 -0
  155. data/spec/dummy/public/app/main.bundle.js +64689 -0
  156. data/spec/dummy/public/app/main.map +1 -0
  157. data/spec/dummy/public/app/styles.bundle.js +364 -0
  158. data/spec/dummy/public/app/styles.map +1 -0
  159. data/spec/factories/boards.rb +5 -0
  160. data/spec/factories/comments.rb +7 -0
  161. data/spec/factories/posts.rb +8 -0
  162. data/spec/factories/user_boards.rb +9 -0
  163. data/spec/factories/users.rb +10 -0
  164. data/spec/models/board_spec.rb +19 -0
  165. data/spec/models/comment_spec.rb +26 -0
  166. data/spec/models/post_spec.rb +19 -0
  167. data/spec/models/user_board_spec.rb +193 -0
  168. data/spec/models/user_spec.rb +5 -0
  169. data/spec/rails_helper.rb +58 -0
  170. data/spec/requests/api/api_boards_spec.rb +238 -0
  171. data/spec/requests/api/api_share_board_spec.rb +167 -0
  172. data/spec/requests/api/api_users_spec.rb +52 -0
  173. data/spec/requests/api/board/api_board_posts_spec.rb +299 -0
  174. data/spec/requests/api/board/post/api_board_post_comments_spec.rb +370 -0
  175. data/spec/requests/render_app_index_spec.rb +19 -0
  176. data/spec/schema/board.json +39 -0
  177. data/spec/schema/comment.json +51 -0
  178. data/spec/schema/post.json +87 -0
  179. data/spec/schema/user.json +27 -0
  180. data/spec/spec_helper.rb +67 -0
  181. data/spec/support/auth_helper.rb +17 -0
  182. data/spec/support/scenario_helper.rb +134 -0
  183. data/spec/support/serialize_helper.rb +37 -0
  184. metadata +540 -0
@@ -0,0 +1,193 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe UserBoard, type: :model do
4
+
5
+ it_behaves_like 'encryptable', [:encrypted_password]
6
+
7
+ before(:each) do
8
+ @user = create(:user)
9
+ @user_2 = create(:user)
10
+ end
11
+
12
+ it "rejects nil board name" do
13
+ board_count = Board.count
14
+ user_board_count = UserBoard.count
15
+ my_board_count = @user.boards.count
16
+
17
+ user_board = UserBoard.new(
18
+ user_id: @user.id,
19
+ is_admin: true,
20
+ encrypted_password: Faker::Crypto.md5
21
+ )
22
+ expect(user_board.save).to be false
23
+ expect(@user.boards.count).to eq my_board_count
24
+ expect(Board.count).to eq(board_count)
25
+ expect(UserBoard.count).to eq(user_board_count)
26
+ end
27
+
28
+ it "rejects nil encrypted_password" do
29
+ user_board_count = UserBoard.count
30
+ my_board_count = @user.boards.count
31
+ board = create(:board)
32
+ board_count = Board.count
33
+
34
+ user_board = UserBoard.new(
35
+ user_id: @user.id,
36
+ board_id: board.id,
37
+ name: Faker::Name.title,
38
+ is_admin: true
39
+ )
40
+ expect(user_board.save).to be false
41
+ expect(@user.boards.count).to eq my_board_count
42
+ expect(Board.count).to eq(board_count)
43
+ expect(UserBoard.count).to eq(user_board_count)
44
+ end
45
+
46
+ it "creates UserBoard and it's Board" do
47
+ board_name = Faker::Name.title
48
+ my_board_count = @user.boards.count
49
+ board_count = Board.count
50
+ user_board_count = UserBoard.count
51
+
52
+ user_board = UserBoard.new(name: board_name, user_id: @user.id, encrypted_password: Faker::Crypto.md5)
53
+ expect(user_board.save).to be true
54
+ expect(@user.boards.count).to eq my_board_count+1
55
+ expect(Board.count).to eq(board_count+1)
56
+ expect(UserBoard.count).to eq(user_board_count+1)
57
+ expect(user_board.board.name).to eq board_name
58
+ end
59
+
60
+ it "updates the board name" do
61
+ new_board_name = Faker::Name.title
62
+ board = create(:board)
63
+ user_board = create(:user_board, {user_id: @user.id, board_id: board.id})
64
+
65
+ board = user_board.board
66
+ user_board.name = new_board_name
67
+ expect(board.name).not_to eq new_board_name
68
+ user_board.save
69
+ board.reload
70
+ expect(board.name).to eq new_board_name
71
+
72
+ end
73
+
74
+ it "updates the encrypted_password" do
75
+ board = create(:board)
76
+
77
+ user_board = create(:user_board, {user_id: @user.id, is_admin: true, board_id: board.id })
78
+
79
+ old_key = user_board.encrypted_password
80
+ new_key = Faker::Crypto.md5
81
+
82
+ expect(user_board.encrypted_password).not_to eq new_key
83
+ user_board.encrypted_password = new_key
84
+ expect(user_board.save).to be true
85
+ expect(user_board.encrypted_password).to eq new_key
86
+
87
+ end
88
+
89
+ it "rejects invalid encrypted_password" do
90
+ board = create(:board)
91
+ user_board = create(:user_board, {user_id: @user.id, is_admin: true, board_id: board.id})
92
+
93
+ old_key = user_board.encrypted_password
94
+
95
+ expect(old_key).not_to be_nil
96
+ user_board.encrypted_password = nil
97
+ expect(user_board.save).to be false
98
+ user_board.reload
99
+ expect(user_board.encrypted_password).to eq old_key
100
+
101
+ end
102
+
103
+ it "doens't update user_boards.encrypted_password if key is the same" do
104
+ new_board_name = Faker::Name.title
105
+ key = Faker::Crypto.md5
106
+ key2 = Faker::Crypto.md5
107
+
108
+ board = create(:board)
109
+
110
+ user_board = create(:user_board, {
111
+ user_id: @user.id,
112
+ board_id: board.id,
113
+ is_admin: true,
114
+ encrypted_password: key
115
+ })
116
+
117
+ user_board_2 = create(:user_board, {
118
+ user_id: @user_2.id,
119
+ board_id: board.id,
120
+ is_admin: false,
121
+ encrypted_password: key2
122
+ })
123
+
124
+ expect(user_board_2.encrypted_password).to eq key2
125
+ user_board.name = new_board_name
126
+ user_board.encrypted_password = key
127
+ user_board.save
128
+ user_board_2.reload
129
+ expect(user_board_2.encrypted_password).to eq key2
130
+
131
+ end
132
+
133
+ it "updates user_boards.encrypted_password if key is new" do
134
+ new_board_name = Faker::Name.title
135
+ key = Faker::Crypto.md5
136
+ key2 = Faker::Crypto.md5
137
+ new_key = Faker::Crypto.md5
138
+ board = create(:board)
139
+ user_board = create(:user_board, {
140
+ user_id: @user.id,
141
+ board_id: board.id,
142
+ is_admin: true,
143
+ encrypted_password: key
144
+ })
145
+
146
+ user_board_2 = create(:user_board, {
147
+ user_id: @user_2.id,
148
+ board_id: board.id,
149
+ is_admin: false,
150
+ encrypted_password: key2
151
+ })
152
+
153
+ expect(user_board_2.encrypted_password).to eq key2
154
+ user_board.name = new_board_name
155
+ user_board.encrypted_password = new_key
156
+ user_board.save
157
+ user_board_2.reload
158
+ expect(user_board_2.encrypted_password).to be_falsy
159
+
160
+ end
161
+
162
+ it "can be shared to other users" do
163
+ user_is_sharing_a_board_scenario
164
+
165
+ new_key = Faker::Crypto.md5
166
+
167
+ user_2_boards_count = @user_2.boards.count
168
+ user_3_boards_count = @user_3.boards.count
169
+ user_4_boards_count = @user_4.boards.count
170
+
171
+ expect(@user_board.share([@user_2.id, @user_3.id, @user_4.id], new_key)).to be true
172
+ # todo: check validation
173
+
174
+ expect(@user_2.boards.count).to eq(user_2_boards_count+1)
175
+ expect(@user_3.boards.count).to eq(user_3_boards_count+1)
176
+ expect(@user_4.boards.count).to eq(user_4_boards_count+1)
177
+
178
+ # make sure none of them is assign admin
179
+ expect(UserBoard.where(
180
+ is_admin: true,
181
+ board_id: @board.id,
182
+ user_id: [@user_2.id, @user_3.id, @user_4.id]
183
+ ).count).to eq 0
184
+
185
+ # make sure all has been shared with
186
+ expect(UserBoard.where(
187
+ board_id: @board.id,
188
+ user_id: [@user_2.id, @user_3.id, @user_4.id]
189
+ ).count).to eq 3
190
+
191
+ end
192
+
193
+ end
@@ -0,0 +1,5 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe User, type: :model do
4
+ # pending "add some examples to (or delete) #{__FILE__}"
5
+ end
@@ -0,0 +1,58 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV['RAILS_ENV'] ||= 'test'
3
+ # require File.expand_path('../../config/environment', __FILE__)
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ # Prevent database truncation if the environment is production
6
+ abort("The Rails environment is running in production mode!") if Rails.env.production?
7
+ require 'spec_helper'
8
+ require 'rspec/rails'
9
+ # Add additional requires below this line. Rails is not loaded until this point!
10
+
11
+ # Requires supporting ruby files with custom matchers and macros, etc, in
12
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
13
+ # run as spec files by default. This means that files in spec/support that end
14
+ # in _spec.rb will both be required and run as specs, causing the specs to be
15
+ # run twice. It is recommended that you do not name files matching this glob to
16
+ # end with _spec.rb. You can configure this pattern with the --pattern
17
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
18
+ #
19
+ # The following line is provided for convenience purposes. It has the downside
20
+ # of increasing the boot-up time by auto-requiring all files in the support
21
+ # directory. Alternatively, in the individual `*_spec.rb` files, manually
22
+ # require only the support files necessary.
23
+ #
24
+ # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
25
+
26
+ # Checks for pending migration and applies them before tests are run.
27
+ # If you are not using ActiveRecord, you can remove this line.
28
+ ActiveRecord::Migration.maintain_test_schema!
29
+
30
+ RSpec.configure do |config|
31
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
32
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
33
+
34
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
35
+ # examples within a transaction, remove the following line or assign false
36
+ # instead of true.
37
+ config.use_transactional_fixtures = true
38
+
39
+ # RSpec Rails can automatically mix in different behaviours to your tests
40
+ # based on their file location, for example enabling you to call `get` and
41
+ # `post` in specs under `spec/controllers`.
42
+ #
43
+ # You can disable this behaviour by removing the line below, and instead
44
+ # explicitly tag your specs with their type, e.g.:
45
+ #
46
+ # RSpec.describe UsersController, :type => :controller do
47
+ # # ...
48
+ # end
49
+ #
50
+ # The different available types are documented in the features, such as in
51
+ # https://relishapp.com/rspec/rspec-rails/docs
52
+ config.infer_spec_type_from_file_location!
53
+
54
+ # Filter lines from Rails gems in backtraces.
55
+ config.filter_rails_from_backtrace!
56
+ # arbitrary gems may also be filtered via:
57
+ # config.filter_gems_from_backtrace("gem name")
58
+ end
@@ -0,0 +1,238 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe "Api::Boards", type: :request do
4
+
5
+ let(:valid_board_params) {
6
+ {
7
+ :board => {:name => "board name"},
8
+ :encrypted_password => Faker::Crypto.md5
9
+ }
10
+ }
11
+ let(:invalid_board_name_param) {
12
+ {
13
+ :board => {:name => nil},
14
+ :encrypted_password => Faker::Crypto.md5
15
+ }
16
+ }
17
+ let(:invalid_encrypted_password_param) {
18
+ {
19
+ :board => {:name => "board name"},
20
+ :encrypted_password => nil
21
+ }
22
+ }
23
+
24
+ describe "GET /api/boards" do
25
+ before(:each) do
26
+ user_has_board_scenario
27
+ end
28
+ it "returns http unauthorized" do
29
+ get api_boards_path
30
+ expect(response).to have_http_status(:unauthorized)
31
+ end
32
+ it "returns current user's boards" do
33
+ get api_boards_path, headers: auth_headers(@user)
34
+ expect(response).to have_http_status(:ok)
35
+ expect(body_to_json('0')).to match_json_schema(:board)
36
+ expect(response.body).to be_json_eql(serialize(@user.user_boards.all))
37
+ end
38
+ end
39
+
40
+ describe "POST /api/boards" do
41
+
42
+ before(:each) do
43
+ create_board_scenario
44
+ end
45
+
46
+ it "returns http unauthorized" do
47
+ post api_boards_path
48
+ expect(response).to have_http_status(:unauthorized)
49
+ end
50
+
51
+ it "rejects invalid board name" do
52
+ prev_boards_count = @user.boards.count
53
+ preve_user_boards_count = @user.user_boards.count
54
+ post api_boards_path, params: invalid_board_name_param, headers: auth_headers(@user), as: :json
55
+ expect(response).to have_http_status(:unprocessable_entity)
56
+ expect(@user.boards.count).to eq(prev_boards_count)
57
+ expect(@user.user_boards.count).to eq(preve_user_boards_count)
58
+ end
59
+
60
+ it "rejects invalid encrypted_password" do
61
+ prev_boards_count = @user.boards.count
62
+ preve_user_boards_count = @user.user_boards.count
63
+ post api_boards_path, params: invalid_encrypted_password_param, headers: auth_headers(@user), as: :json
64
+ expect(response).to have_http_status(:unprocessable_entity)
65
+ expect(@user.boards.count).to eq(prev_boards_count)
66
+ expect(@user.user_boards.count).to eq(preve_user_boards_count)
67
+ end
68
+
69
+ it "creates new board" do
70
+ prev_boards_count = @user.boards.count
71
+ preve_user_boards_count = @user.user_boards.count
72
+ post api_boards_path, params: valid_board_params, headers: auth_headers(@user), as: :json
73
+ expect(response).to have_http_status(:created)
74
+ expect(parse_json(response.body)).to match_json_schema(:board)
75
+ expect(body_to_json["board"]["name"]).to eq(valid_board_params[:board][:name])
76
+ expect(body_to_json["encrypted_password"]).to eq(valid_board_params[:encrypted_password])
77
+ expect(body_to_json["is_admin"]).to be true
78
+ end
79
+ end
80
+
81
+ context "My Boards" do
82
+
83
+ before(:each) do
84
+ user_has_shared_board_scenario
85
+ end
86
+
87
+ describe "GET /api/boards/:id" do
88
+
89
+ it "returns http unauthorized" do
90
+ get api_board_path(@board)
91
+ expect(response).to have_http_status(:unauthorized)
92
+ end
93
+
94
+ it "returns http not_found" do
95
+ get api_board_path({id: 1000000}), headers: auth_headers(@user)
96
+ expect(response).to have_http_status(:not_found)
97
+ end
98
+
99
+ it "returns http forbidden" do
100
+ get api_board_path(@board), headers: auth_headers(@user_2)
101
+ expect(response).to have_http_status(:forbidden)
102
+ end
103
+
104
+ it "returns board resource" do
105
+ # debugger
106
+ get api_board_path(@board), headers: auth_headers(@user)
107
+ # debugger
108
+ expect(response).to have_http_status(:ok)
109
+ expect(response.body).to match_json_schema(:board)
110
+ expect(response.body).to be_json_eql(serialize(@user_board))
111
+ end
112
+ end
113
+
114
+ describe "PUT /api/boards/:id" do
115
+
116
+ it "returns http unauthorized" do
117
+ put api_board_path(@board)
118
+ expect(response).to have_http_status(:unauthorized)
119
+ end
120
+
121
+ it "returns http forbidden" do
122
+ put api_board_path(@board), params: valid_board_params, headers: auth_headers(@user_2), as: :json
123
+ expect(response).to have_http_status(:forbidden)
124
+ end
125
+
126
+ it "returns http not_found" do
127
+ put api_board_path({id: 1000000}), params: valid_board_params, headers: auth_headers(@user), as: :json
128
+ expect(response).to have_http_status(:not_found)
129
+ end
130
+
131
+ it "rejects invalide encrypted_password" do
132
+ put api_board_path(@board), params: invalid_encrypted_password_param, headers: auth_headers(@user), as: :json
133
+ expect(response).to have_http_status(:unprocessable_entity)
134
+ @board.reload
135
+ @user_board.reload
136
+ expect(@board.name).not_to eq(invalid_encrypted_password_param[:board][:name])
137
+ expect(@user_board.encrypted_password).not_to eq(invalid_encrypted_password_param[:encrypted_password])
138
+ end
139
+
140
+ it "accepts invalid board name" do
141
+ put api_board_path(@board), params: invalid_board_name_param, headers: auth_headers(@user), as: :json
142
+ expect(response).to have_http_status(:ok)
143
+ @board.reload
144
+ @user_board.reload
145
+ expect(@board.name).not_to be_falsy
146
+ expect(@user_board.encrypted_password).to eq(invalid_board_name_param[:encrypted_password])
147
+ end
148
+
149
+ it "updates the board resource" do
150
+ put api_board_path(@board), params: valid_board_params, headers: auth_headers(@user), as: :json
151
+ expect(response).to have_http_status(:ok)
152
+ expect(response.body).to match_json_schema(:board)
153
+ expect(body_to_json['board']['name']).to eq(valid_board_params[:board][:name])
154
+ expect(body_to_json['encrypted_password']).to eq(valid_board_params[:encrypted_password])
155
+ @user_board.reload
156
+ expect(response.body).to be_json_eql(serialize(@user_board))
157
+ expect(@board.user_boards.where.not(encrypted_password: '').first).to eq @user_board
158
+ expect(@board.user_boards.where.not(encrypted_password: '').count).to eq 1
159
+ expect(@shared_board.user_boards.where.not(encrypted_password: '').all).not_to be_nil
160
+ end
161
+ end
162
+
163
+ describe "DELETE /api/boards/:id" do
164
+
165
+ it "returns http unauthorized" do
166
+ delete api_board_path(@board)
167
+ expect(response).to have_http_status(:unauthorized)
168
+ end
169
+
170
+ it "returns http forbidden if not board owner" do
171
+ delete api_board_path(@board), headers: auth_headers(@user_2), as: :json
172
+ expect(response).to have_http_status(:forbidden)
173
+ end
174
+
175
+ it "returns http not_found" do
176
+ delete api_board_path({id: 1000000}), headers: auth_headers(@user), as: :json
177
+ expect(response).to have_http_status(:not_found)
178
+ end
179
+
180
+ it "deletes the board resource and its post and comments" do
181
+ expect(Board.find_by_id(@board.id)).not_to be_nil
182
+ expect(UserBoard.where(board_id: @board.id).all).not_to be_empty
183
+ expect(Post.where(board_id: @board.id).all).not_to be_empty
184
+ expect(Comment.where(post_id: @post.id).all).not_to be_empty
185
+ expect{delete api_board_path(@board), headers: auth_headers(@user), as: :json}
186
+ .to change{@user.boards.count}.by(-1)
187
+ expect(response).to have_http_status(:ok)
188
+ expect(Board.find_by_id(@board.id)).to be_nil
189
+ expect(UserBoard.where(board_id: @board.id).all).to be_empty
190
+ expect(Post.where(board_id: @board.id).all).to be_empty
191
+ expect(Comment.where(post_id: @post.id).all).to be_empty
192
+ end
193
+ end
194
+ end
195
+
196
+ context "Shared Board" do
197
+
198
+ before(:each) do
199
+ user_has_shared_board_scenario
200
+ end
201
+
202
+ describe "GET /api/boards/:id" do
203
+
204
+ it "returns http unauthorized" do
205
+ get api_board_path(@shared_board)
206
+ expect(response).to have_http_status(:unauthorized)
207
+ end
208
+
209
+ it "returns board resource" do
210
+ get api_board_path(@shared_board), headers: auth_headers(@user_2)
211
+ expect(response).to have_http_status(:ok)
212
+ expect(response.body).to match_json_schema(:board)
213
+ expect(response.body).to be_json_eql(serialize(@shared_user_board_2))
214
+ end
215
+ end
216
+
217
+ describe "PUT /api/boards/:id" do
218
+ it "updates the board resource" do
219
+ put api_board_path(@shared_board), params: valid_board_params, headers: auth_headers(@user_2), as: :json
220
+ expect(response).to have_http_status(:forbidden)
221
+ @shared_board.reload
222
+ expect(@shared_board.name).not_to eq(valid_board_params[:board][:name])
223
+ expect(@shared_user_board_2.encrypted_password).not_to eq(valid_board_params[:encrypted_password])
224
+ end
225
+ end
226
+
227
+ describe "DELETE /api/boards/:id" do
228
+
229
+ it "returns http forbidden if not board owner" do
230
+ delete api_board_path(@shared_board), headers: auth_headers(@user_2), as: :json
231
+ expect(response).to have_http_status(:forbidden)
232
+ expect(Board.find(@shared_board.id)).not_to be_nil
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ end
@@ -0,0 +1,167 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe "Api::ShareBoard", type: :request do
4
+
5
+ before(:each) do
6
+ user_is_sharing_a_board_scenario
7
+ end
8
+
9
+ describe "POST /api/share/board/:id" do
10
+
11
+ it "returns http unauthorized status" do
12
+ post(
13
+ api_share_board_path,
14
+ as: :json
15
+ )
16
+
17
+ expect(response).to have_http_status(:unauthorized)
18
+ end
19
+
20
+ it "returns http forbidden status when not board owner" do
21
+ post(
22
+ api_share_board_path,
23
+ headers: auth_headers(@user_2),
24
+ params: @payload,
25
+ as: :json
26
+ )
27
+ expect(response).to have_http_status(:forbidden)
28
+ end
29
+
30
+ it "returns http forbidden status when not board owner" do
31
+ post(
32
+ api_share_board_path,
33
+ headers: auth_headers(@user_2),
34
+ params: @payload_wo_posts,
35
+ as: :json
36
+ )
37
+ expect(response).to have_http_status(:forbidden)
38
+ end
39
+
40
+ it "returns unprocessable_entity http status if empty payload" do
41
+ post(
42
+ api_share_board_path,
43
+ headers: auth_headers(@user),
44
+ params: {},
45
+ as: :json
46
+ )
47
+ expect(response).to have_http_status(:unprocessable_entity)
48
+ end
49
+
50
+ it "returns unprocessable_entity http status if no encrypted_password" do
51
+ post(
52
+ api_share_board_path,
53
+ headers: auth_headers(@user),
54
+ params: @payload_wo_encrypted_password,
55
+ as: :json
56
+ )
57
+ expect(response).to have_http_status(:unprocessable_entity)
58
+ end
59
+
60
+ it "returns unprocessable_entity http status if no shared user ids" do
61
+ post(
62
+ api_share_board_path,
63
+ headers: auth_headers(@user),
64
+ params: @payload_wo_shared_user_ids,
65
+ as: :json
66
+ )
67
+ expect(response).to have_http_status(:unprocessable_entity)
68
+ end
69
+
70
+ it "returns unprocessable_entity http status if contains invalid post" do
71
+ post(
72
+ api_share_board_path,
73
+ headers: auth_headers(@user),
74
+ params: @payload_w_invalid_post,
75
+ as: :json
76
+ )
77
+ expect(response).to have_http_status(:unprocessable_entity)
78
+ end
79
+
80
+ it "returns unprocessable_entity http status if contains invalid comment" do
81
+ post(
82
+ api_share_board_path,
83
+ headers: auth_headers(@user),
84
+ params: @payload_w_invalid_comment,
85
+ as: :json
86
+ )
87
+ expect(response).to have_http_status(:unprocessable_entity)
88
+ end
89
+
90
+
91
+ it "should successfully share board even if no comments" do |variable|
92
+ user_2_boards_count = @user_2.boards.count
93
+ user_3_boards_count = @user_3.boards.count
94
+ user_4_boards_count = @user_4.boards.count
95
+
96
+ prev_post_hash = @post.attributes
97
+ prev_comment_hash = @comment.attributes
98
+
99
+ post(
100
+ api_share_board_path,
101
+ headers: auth_headers(@user),
102
+ params: @payload_wo_comments,
103
+ as: :json
104
+ )
105
+
106
+ expect(response).to have_http_status(:ok)
107
+ expect(@user_2.boards.count).to eq(user_2_boards_count+1)
108
+ expect(@user_3.boards.count).to eq(user_3_boards_count+1)
109
+ expect(@user_4.boards.count).to eq(user_4_boards_count+1)
110
+
111
+ expect(@post.reload.title).to eq @payload_wo_comments[:posts][0][:title.to_s]
112
+ expect(@post.reload.content).to eq @payload_wo_comments[:posts][0][:content.to_s]
113
+
114
+ end
115
+
116
+
117
+ it "should successfully share board even if no posts" do |variable|
118
+ user_2_boards_count = @user_2.boards.count
119
+ user_3_boards_count = @user_3.boards.count
120
+ user_4_boards_count = @user_4.boards.count
121
+
122
+ prev_post_hash = @post.attributes
123
+ prev_comment_hash = @comment.attributes
124
+
125
+ post(
126
+ api_share_board_path,
127
+ headers: auth_headers(@user),
128
+ params: @payload_wo_posts,
129
+ as: :json
130
+ )
131
+
132
+ expect(response).to have_http_status(:ok)
133
+ expect(@user_2.boards.count).to eq(user_2_boards_count+1)
134
+ expect(@user_3.boards.count).to eq(user_3_boards_count+1)
135
+ expect(@user_4.boards.count).to eq(user_4_boards_count+1)
136
+
137
+ end
138
+
139
+ it "should successfully share valid payload" do |variable|
140
+ user_2_boards_count = @user_2.boards.count
141
+ user_3_boards_count = @user_3.boards.count
142
+ user_4_boards_count = @user_4.boards.count
143
+
144
+ prev_post_hash = @post.attributes
145
+ prev_comment_hash = @comment.attributes
146
+
147
+ post(
148
+ api_share_board_path,
149
+ headers: auth_headers(@user),
150
+ params: @payload,
151
+ as: :json
152
+ )
153
+
154
+ expect(response).to have_http_status(:ok)
155
+ expect(@user_2.boards.count).to eq(user_2_boards_count+1)
156
+ expect(@user_3.boards.count).to eq(user_3_boards_count+1)
157
+ expect(@user_4.boards.count).to eq(user_4_boards_count+1)
158
+
159
+ expect(@post.reload.title).to eq @payload[:posts][0][:title.to_s]
160
+ expect(@post.reload.content).to eq @payload[:posts][0][:content.to_s]
161
+ expect(@comment.reload.content).to eq @payload[:posts][0][:comments][0][:content.to_s]
162
+
163
+ end
164
+
165
+ end
166
+
167
+ end