Merge branch 'dev_aliyun' of http://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_home
cxt 5 years ago
commit cfc6dbbae6

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

@ -0,0 +1,3 @@
// Place all the styles related to the HackUserLastestCodes controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -0,0 +1,3 @@
// Place all the styles related to the hacks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -395,6 +395,50 @@ class ApplicationController < ActionController::Base
end
end
# 处理返回非0就报错的请求
def interface_post(uri, params, status, message)
begin
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
uid_logger_dubug("--uri_exec: .....res is #{res}")
res = JSON.parse(res)
if (res && res['code'] != 0)
tip_exception(status, message)
else
res
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
raise Educoder::TipException.new("实训平台繁忙繁忙等级84")
end
end
# json格式请求
def interface_json_post(uri, params, status, message)
begin
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.start(uri.host, uri.port) do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = params.to_json
http.request(req)
end
uid_logger_dubug("--uri_exec: .....res is #{res.body}")
res = JSON.parse(res.body)
if (res && res['code'] != 0)
tip_exception(status, message)
else
res
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
raise Educoder::TipException.new("服务器繁忙")
end
end
# 适用与已经用url_safe编码后回调字符串形式
def tran_base64_decode64(str)
s_size = str.size % 4

@ -0,0 +1,170 @@
class HackUserLastestCodesController < ApplicationController
before_action :require_login, except: [:listen_result]
before_action :find_my_hack, only: [:show, :code_debug, :code_submit, :update_code, :listen_result, :result]
before_action :update_user_hack_status, only: [:code_debug, :code_submit]
before_action :require_auth_identity, only: [:update_code]
before_action :require_manager_identity, only: [:update_code]
def show
@my_hack.update_attribute(:status, 0) if @my_hack.status == 1
end
def update_code
@my_hack.update_attribute(:code, params[:code])
end
# 调试代码
def code_debug
exec_mode = "debug"
error_status = 501
error_msg = "debug_error"
oj_evaluate exec_mode, error_status, error_msg
render_ok
end
# 提交
def code_submit
exec_mode = "submit"
error_status = 502
error_msg = "submit_error"
oj_evaluate exec_mode, error_status, error_msg
render_ok
end
# 提交结果显示
def result
return if @my_hack.status == 1
end
# 接收中间件返回结果接口
# 调试模式: status 0 表示评测无错误,其他 表示错误(如编译出错,执行出错,超时等)
def listen_result
logger.info("###########listen_result#{params}")
begin
ojEvaResult = JSON.parse(params[:ojEvaResult])
testCase = ojEvaResult['testCase']
# 只有编译出错时,才正则匹配错误行数
error_line=
if params[:status] == "-4"
regular_match_error_line ojEvaResult['outPut'], @my_hack.hack.language
end
# debug 与submit 公用的参数
ds_params = {input: testCase['input'], output: testCase['output'], hack_id: @hack.id,
code: ojEvaResult['codeFileContent'], user_id: @my_hack.user_id, error_line: error_line,
status: ojEvaResult['status'], error_msg: ojEvaResult['outPut'],
execute_time: ojEvaResult['executeTime'], execute_memory: ojEvaResult['executeMem']}
ActiveRecord::Base.transaction do
# debug模式与submit模式
if ojEvaResult['execMode'] == "debug"
save_debug_data ds_params
elsif ojEvaResult['execMode'] == "submit"
save_submit_data ds_params
end
# 评测完成后,还原评测中的状态
@my_hack.update_attribute(:submit_status, 0)
end
render_ok
rescue Exception => e
logger.error("#########listen_result: #{e.message}")
end
end
private
def find_my_hack
@my_hack = HackUserLastestCode.find_by(identifier: params[:identifier])
@hack = @my_hack.hack
end
def oj_evaluate exec_mode, error_status, error_msg
request_url = "#{edu_setting('cloud_bridge')}/bridge/ojs/evaluate"
test_sets =
if exec_mode == "submit"
@hack.hack_sets.map{|set| {input: set.input, output: set.output, caseId: set.id}}
else
{input: params[:input]}
end
testCases = Base64.urlsafe_encode64(test_sets.to_json)
#codeFileContent = Base64.urlsafe_encode64(@my_hack.code)
debug_params = {execMode: exec_mode,
tpiID: @my_hack.identifier,
testCases: testCases,
platform: @my_hack.language,
codeFileContent: @my_hack.code,
timeLimit: @hack.time_limit,
sec_key: Time.now.to_i}
interface_json_post request_url, debug_params, error_status, error_msg
# 每次评测提交数增加
@hack.increment!(:submit_num)
end
# 正则错误行数
def regular_match_error_line content, language
case language
when 'Java'
content.scan(/.java.\d+/).map{|s| s.match(/\d+/)[0].to_i}.min
when 'C', 'C++'
content.scan(/\d:\d+: error/).map{|s| s.match(/\d+/)[0]}.min
when 'Python'
content.scan(/line \d+/).map{|s| s.match(/\d+/)[0].to_i}.min
end
end
# 存储debug数据
def save_debug_data debug_params
if @my_hack.hack_user_debug.present?
@my_hack.hack_user_debug.update_attributes!(debug_params)
else
@my_hack.hack_user_debug.create!(debug_params)
end
end
# 存储submit数据
def save_submit_data submit_params
# 通关
if submit_params[:status] == "0"
# 编程题已经发布,且之前未通关奖励积分
if @hack.status == 1 && !@my_hack.passed?
reward_attrs = { container_id: game.id, container_type: 'Hack', score: @hack.score }
RewardGradeService.call(@my_hack.user, reward_attrs)
RewardExperienceService.call(@my_hack.user, reward_attrs)
# 评测完成更新通过数
@hack.increment!(:pass_num)
@my_hack.update_attribute(:passed, true)
end
end
# 创建用户评测记录
logger.info("###########submit_params:#{submit_params}")
query_index = @my_hack.hack_user_codes.count +1
@my_hack.hack_user_codes.create!(submit_params.merge(query_index: query_index))
end
# 调试或提交改变状态
def update_user_hack_status
@my_hack.update_attribute(:submit_status, 1)
end
# 只有自己才能改动代码
def require_identity
if @my_hack.user_id != current_user.id
tip_exception(403, "..")
end
end
# 老师、自己、管理可以查看他人的编程题
def require_manager_identity
unless current_user.certification_teacher? || admin_or_business? || @my_hack.user_id == current_user.id
tip_exception(403, "..")
end
end
# 只有自己才能评测
def require_auth_identity
unless @my_hack.user_id == current_user.id
tip_exception(403, "..")
end
end
end

@ -0,0 +1,180 @@
class HacksController < ApplicationController
before_action :require_login, except: [:index]
before_action :require_teacher_identity, only: [:create, :edit, :update]
before_action :require_auth_identity, only: [:update, :edit, :publish]
before_action :find_hack, only: [:edit, :update, :publish, :start]
# 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可
def start
# 未发布的编程题,只能作者、或管理员访问
start_hack_auth
user_hack = @hack.hack_user_lastest_codes.mine(current_user.id)
identifier =
if user_hack.present?
user_hack.identifier
else
user_identifier = generate_identifier HackUserLastestCode, 12
user_code = {user_id: current_user.id, code: @hack.code,
identifier: user_identifier, language: @hack.language}
@hack.hack_user_lastest_codes.create!(user_code)
user_identifier
end
render_ok(data: {identifier: identifier})
end
# 首页
def index
# 筛选过滤与排序
params_filter_or_order
# 我解决的编程题数
user_codes = HackUserLastestCode.mine(current_user).passed.joins(:hack)
@simple_count = user_codes.where(hacks: {difficult: 1}).count
@medium_count = user_codes.where(hacks: {difficult: 2}).count
@diff_count = user_codes.where(hacks: {difficult: 3}).count
@pass_count = @simple_count + @medium_count + @diff_count
@hacks_count = @hacks.count("hacks.id")
@hacks = paginate @hacks
end
def create
begin
logger.info("##########{hack_params}")
hack = Hack.new(hack_params)
ActiveRecord::Base.transaction do
hack.user_id = current_user.id
hack.identifier = generate_identifier Hack, 8
hack.save!
# 创建测试集与代码
hack.hack_sets.create!(hack_sets_params)
hack.hack_codes.create!(hack_code_params)
end
render_ok({identifier: hack.identifier})
rescue Exception => e
logger.error("########create_hack_error: #{e.message}")
render_error("创建失败")
end
end
def update
begin
ActiveRecord::Base.transaction do
@hack.update_attributes!(hack_params)
set_ids = @hack.hack_sets.pluck(:id)
# 更新
param_update_sets params[:update_hack_sets], set_ids
# 新建
@hack.hack_sets.create!(hack_sets_params)
# 更新代码
@hack.hack_codes.create!(hack_code_params)
end
render_ok
rescue Exception => e
logger.error("####update_hack_error: #{e.message}")
render_error("更新失败")
end
end
# 发布功能
def publish
@hack.update_attribute(:status, 1)
render_ok
end
# 发布列表
def unpulished_list
limit = params[:limit] || 16
page = params[:page] || 1
hacks = Hack.where(user_id: current_user.id, status: 0)
@hacks_count = hacks.count
@hacks = hacks.includes(:hack_sets).page(page).per(limit)
end
def edit;end
private
# 实名认证老师,管理员与运营人员权限
def require_teacher_identity
unless current_user.certification_teacher? || admin_or_business?
tip_exception(403, "..")
end
end
# 只有自己,或者管理员才能更新
def require_auth_identity
unless @hack.user_id == current_user.id || admin_or_business?
tip_exception(403, "..")
end
end
def find_hack
@hack = Hack.find_by_identifier(params[:identifier])
end
def hack_params
params.require(:hack).permit(:name, :description, :difficult, :category, :open_or_not, :time_limit, :score)
end
def hack_sets_params
params.permit(hack_sets: [:input, :output, :position])[:hack_sets]
end
def hack_code_params
params.require(:hack_codes).permit(:code, :language)
end
def publish_params
params.require(:hack).permit(:difficult, :category, :open_or_not, :time_limit, :score)
end
def param_update_sets sets, all_sets_id
delete_set_ids = all_sets_id - sets.map{|set|set[:id]}
@hack.hack_sets.where(id: delete_set_ids).destroy_all
sets.each do |set|
if all_sets_id.include?(set[:id])
update_attrs = {input: set[:input], output: set[:output], position: set[:position]}
@hack.hack_sets.find_by!(id: set[:id]).update_attributes(update_attrs)
end
end
end
def params_filter_or_order
# 如果有来源,就不管发布公开私有
select_sql = "hacks.*, if(hacks.hack_user_lastest_codes_count=0, 0, hacks.pass_num/hacks.hack_user_lastest_codes_count) passed_rate"
if params[:come_from]
hacks = Hack.select(select_sql).mine(current_user.id)
else
hacks = Hack.select(select_sql).published.opening
end
# 搜索
if params[:search]
hacks = hacks.where("name like ?", "%#{params[:search]}%")
end
# 难度
if params[:difficult]
hacks = hacks.where(difficult: params[:difficult])
end
# 状态
if params[:status]
user_hacks = HackUserLastestCode.where(user_id: current_user.id)
if params[:status].to_i == -1
if user_hacks.present?
hacks = hacks.where.not(id: user_hacks.pluck(:hack_id))
end
else
hacks = hacks.joins(:hack_user_lastest_code).where(hack_user_lastest_code: {status: params[:status]})
end
end
# 排序
sort_by = params[:sort_by] || "hack_user_lastest_codes_count"
sort_direction = params[:sort_direction] || "desc"
@hacks = hacks.order("#{sort_by} #{sort_direction}")
end
def start_hack_auth
return true if @hack == 1
require_auth_identity
end
end

@ -489,10 +489,7 @@ class ShixunsController < ApplicationController
ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
end
end
logger.info("#########shixun_params#{shixun_params}")
@shixun.update_attributes(shixun_params)
logger.info("##########shixun_info_params: #{shixun_info_params}")
logger.info("##########params[:shixun_info][:evaluate_script]: #{params[:shixun_info][:evaluate_script]}")
@shixun.shixun_info.update_attributes(shixun_info_params)
@shixun.shixun_schools.delete_all
# scope_partment: 高校的名称

@ -0,0 +1,2 @@
module HackUserLastestCodesHelper
end

@ -0,0 +1,2 @@
module HacksHelper
end

@ -0,0 +1,38 @@
class Hack < ApplicationRecord
# status: 0 未发布; 1已发布
# diffcult: 难度 1简单2中等 3困难
# 编程题
validates_length_of :name, maximum: 60
# 测试集
has_many :hack_sets, ->{order("position asc")}, :dependent => :destroy
# 代码
has_many :hack_codes, :dependent => :destroy
has_many :hack_user_lastest_codes, :dependent => :destroy
belongs_to :user
scope :published, -> { where(status: 1) }
scope :opening, -> {where(open_or_not: 1)}
scope :mine, -> (author_id){ where(user_id: author_id) }
def language
if hack_codes.count == 1
hack_codes.first.language
else
hack_codes.pluck(:language).first
end
end
def code
if hack_codes.count == 1
tran_base64_decode64(hack_codes.first.code)
else
tran_base64_decode64(hack_codes.pluck(:code))
end
end
# 用于用户调试的第一个测试用例
def input_test_case
hack_sets.first&.input
end
end

@ -0,0 +1,3 @@
class HackCode < ApplicationRecord
# 编程题代码相关
end

@ -0,0 +1,4 @@
class HackSet < ApplicationRecord
# 编程题测试集
belongs_to :hack
end

@ -0,0 +1,4 @@
class HackUserCode < ApplicationRecord
# 用户编程题的信息
belongs_to :hack
end

@ -0,0 +1,4 @@
class HackUserDebug < ApplicationRecord
belongs_to :hack
belongs_to :hack_user_lastest_code
end

@ -0,0 +1,13 @@
class HackUserLastestCode < ApplicationRecord
# passed 用户之前评测是否通过
# status: 最新评测状态: -1测试用例结果不匹配; 0: 评测通过; ;2 评测超时;3 创建pod失败; 4 编译失败;5 执行失败
# submit_status: 0: 可以评测, 1评测中
# 编程题最新代码
belongs_to :hack, counter_cache: true
belongs_to :user
has_many :hack_user_codes, dependent: :destroy
has_one :hack_user_debug
scope :mine, ->(author_id){ find_by(user_id: author_id) }
scope :passed, -> {where(status: 1)}
end

@ -149,6 +149,9 @@ class User < ApplicationRecord
# 客户管理
has_many :partner_managers, dependent: :destroy
# OJ编程题
has_many :hacks, dependent: :destroy
has_many :hack_user_lastest_codes, dependent: :destroy
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
@ -696,10 +699,6 @@ class User < ApplicationRecord
LimitForbidControl::UserLogin.new(self).clear
end
def from_sub_site?
laboratory_id.present? && laboratory_id != 1
end
protected
def validate_password_length
# 管理员的初始密码是5位

@ -0,0 +1,12 @@
json.hack do
json.(@hack, :difficult, :time_limit, :description, :score, :identifier)
json.language @hack.language
json.username @hack.user.real_name
json.code @my_hack.code
json.pass_count @hack.pass_num
json.submit_count @hack.submit_num
end
json.test_case do
json.input @hack.input_test_case
end

@ -0,0 +1,13 @@
# 编程内容
json.(@hack, :name, :description, :language, :code)
# 代码
json.language @hack.language
json.code @hack.code
# 测试集
json.hack_sets do
json.array! @hack.hack_sets do |set|
json.(set, :id, :input, :output, :position)
end
end

@ -0,0 +1,13 @@
json.top_data do
json.passed_count @pass_count
json.simple_count @simple_count
json.medium_count @medium_count
json.diff_count @diff_count
end
json.hacks_count @hacks_count
json.hacks_list do
json.array! @hacks do |hack|
json.(hack,:identifier, :name , :hack_user_lastest_codes_count, :difficult, :passed_rate, :category)
end
end

@ -0,0 +1,5 @@
json.hacks_count @hacks_count
json.hacks @hacks do |hack|
json.(hack, :name, :difficult, :updated_at)
json.sets_count hack.hack_sets.count
end

@ -35,6 +35,28 @@ Rails.application.routes.draw do
end
end
resources :hacks, path: :problems, param: :identifier do
collection do
get :unpulished_list
end
member do
post :publish
get :start
get :result
end
end
resources :hack_user_lastest_codes, path: :myproblems, param: :identifier do
member do
post :update_code
get :code_debug
get :code_submit
match :listen_result, :via => [:get, :post]
end
end
resources :tem_tests
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
#
@ -64,7 +86,7 @@ Rails.application.routes.draw do
resources :shixuns, only: [:index]
resources :projects, only: [:index]
resources :subjects, only: [:index]
# resources :question_banks, only: [:index]
# hacks :question_banks, only: [:index]
resource :experience_records, only: [:show]
resource :grade_records, only: [:show]
resource :watch, only: [:create, :destroy]

@ -0,0 +1,20 @@
class CreateHacks < ActiveRecord::Migration[5.2]
def change
create_table :hacks do |t|
t.string :name
t.integer :difficult
t.integer :category
t.integer :status, default: 0
t.boolean :open_or_not, default: true
t.integer :time_limit
t.integer :memory_limit
t.string :identifier
t.references :user
t.text :description
t.timestamps
end
add_index :hacks, :identifier, unique: true
end
end

@ -0,0 +1,11 @@
class CreateHackCodes < ActiveRecord::Migration[5.2]
def change
create_table :hack_codes do |t|
t.references :hack
t.text :code
t.string :language
t.timestamps
end
end
end

@ -0,0 +1,13 @@
class CreateHackSets < ActiveRecord::Migration[5.2]
def change
create_table :hack_sets do |t|
t.references :hack
t.text :input
t.text :output
t.integer :position
t.timestamps
end
add_index :hack_sets, [:hack_id, :position], unique: true
end
end

@ -0,0 +1,18 @@
class CreateHackUserCodes < ActiveRecord::Migration[5.2]
def change
create_table :hack_user_codes do |t|
t.references :user
t.references :hack
t.text :code
t.text :output
t.text :error_msg
t.integer :error_line
t.integer :position
t.integer :status, default: 0
t.integer :query_index
t.timestamps
end
add_index :hack_user_codes, [:user_id, :hack_id, :query_index], unique: true
end
end

@ -0,0 +1,12 @@
class CreateHackUserLastestCodes < ActiveRecord::Migration[5.2]
def change
create_table :hack_user_lastest_codes do |t|
t.references :user
t.references :hack
t.text :code
t.timestamps
end
add_index :hack_user_lastest_codes, [:user_id, :hack_id], unique: true
end
end

@ -0,0 +1,14 @@
class CreateHackUserDebugs < ActiveRecord::Migration[5.2]
def change
create_table :hack_user_debugs do |t|
t.references :user
t.references :hack
t.text :output
t.text :input
t.text :error_msg
t.integer :error_line
t.timestamps
end
end
end

@ -0,0 +1,7 @@
class AddDefualtForHacks < ActiveRecord::Migration[5.2]
def change
change_column :hacks, :status, :integer, :default => 0
change_column :hacks, :open_or_not, :boolean, :default => true
change_column :hack_user_codes, :status, :integer, :default => 0
end
end

@ -0,0 +1,5 @@
class AddScoreForHacks < ActiveRecord::Migration[5.2]
def change
add_column :hacks, :score, :integer
end
end

@ -0,0 +1,27 @@
class AddStatusEndTimeForHackUserLastestCode < ActiveRecord::Migration[5.2]
def change
add_column :hack_user_lastest_codes, :passed, :boolean, :default => false
add_column :hack_user_lastest_codes, :pass_time, :timestamp
add_column :hack_user_lastest_codes, :identifier, :string
add_column :hack_user_lastest_codes, :language, :string
add_column :hack_user_debugs, :hack_user_lastest_code_id, :integer
add_column :hacks, :hack_user_lastest_codes_count, :integer, :default => 0
add_column :hacks, :pass_num, :integer, :default => 0
add_column :hacks, :submit_num, :integer, :default => 0
add_column :hack_user_codes, :input, :text
add_index :hack_user_lastest_codes, :user_id, name: "user_index"
add_index :hack_user_lastest_codes, :hack_id, name: "hack_index"
add_index :hack_user_lastest_codes, :identifier, unique: true
add_index :hack_user_debugs, :hack_user_lastest_code_id, unique: true
add_column :hack_user_lastest_codes, :submit_status, :integer, :default => 0
add_column :hack_user_lastest_codes, :status, :integer
add_column :hack_user_lastest_codes, :passed_time, :timestamp
add_column :hack_user_debugs, :status, :integer
add_column :hack_user_codes, :execute_time, :integer
add_column :hack_user_codes, :execute_memory, :integer
add_column :hack_user_debugs, :execute_time, :integer
add_column :hack_user_debugs, :execute_memory, :integer
end
end

@ -0,0 +1,7 @@
class AddHackUserLastestCodeIdForHackUserCode < ActiveRecord::Migration[5.2]
def change
add_column :hack_user_codes, :hack_user_lastest_code_id, :integer
add_index :hack_user_codes, :hack_user_lastest_code_id
end
end

@ -29512,7 +29512,7 @@ var Player = function (_BaseObject) {
* @prop {boolean} controls
* enabled/disables displaying controls
* @prop {boolean} crossOrigin
* enables cross-origin capability for media-resources
* enables cross-origin capability for media-hacks
* @prop {boolean} playInline
* enables in-line video elements
* @prop {boolean} audioOnly

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -22,6 +22,7 @@ import TPICodeMirror from '../component/TPICodeMirror'
import TPIMonaco from '../component/monaco/TPIMonaco'
import { loadSshScript, openTerminal } from './Webssh'
import { Modal } from 'antd';
const $ = window.$;
@ -114,8 +115,28 @@ class CodeRepositoryView extends Component {
// $('#codetab_con_1').append(``)
// $('#codetab_con_1 .codemirrorBackground').hide()
window.addEventListener('beforeunload', this.beforeUnload);
}
componentWillUnmount () {
window.removeEventListener('beforeunload', this.beforeUnload);
}
beforeUnload = (e) => {
// console.log(this.props);
const { game } = this.props;
const url = `/api/tasks/${game.identifier}/cost_time.json`;
axios.get(url).then(res => {
// TODO
});
const msg = '确定要离开吗?';
e = e || window.event;
if (e) {
e.returnValue = msg;
}
return msg;
}
onTreeSelect = (selectedKeys, info) => {
if (!info.node.isLeaf()) {
const expandedKeys = this.state.expandedKeys.slice(0)
@ -223,7 +244,7 @@ class CodeRepositoryView extends Component {
// js_min_all.js有同样的计算逻辑用来拖拽时计算ssh高宽
// TODO 结合new Terminal 时的fontSize参数来定高度
const gameCtx = $("#games_repository_contents");
gameCtx.css({'padding-bottom': '50px', 'background': '#000'});
gameCtx.css({'padding-bottom': '30px', 'background': '#000'});
var h = gameCtx.height() - 50;
var w = gameCtx.width();
var line_h = (navigator.userAgent.indexOf('Chrome') >= 0 ? 18 : 19);
@ -543,13 +564,13 @@ class CodeRepositoryView extends Component {
{/* { tabIndex === STABLE_SSH_TAB_ID && this.state.sshData && <Webssh {...this.state.sshData} ></Webssh> } */}
</div>
<div id="codetab_con_82" className="undis -relative"
style={ { color: '#fff', display: tabIndex === 82 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '50px' } }>
style={ { color: '#fff', display: tabIndex === 82 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px' } }>
</div>
<div id="codetab_con_83" className="undis -relative"
style={ { color: '#fff', display: tabIndex === 83 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '50px'} }>
style={ { color: '#fff', display: tabIndex === 83 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px'} }>
</div>
<div id="codetab_con_84" className="undis -relative"
style={ { color: '#fff', display: tabIndex === 84 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '50px'} }>
style={ { color: '#fff', display: tabIndex === 84 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px'} }>
</div>
<div id="codetab_con_3" className="undis -relative" style={{display: 'none'}}></div>
</React.Fragment>

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackUserLastestCodesController, type: :controller do
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HacksController, type: :controller do
end

@ -0,0 +1,15 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the HackUserLastestCodesHelper. For example:
#
# describe HackUserLastestCodesHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe HackUserLastestCodesHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,15 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the HacksHelper. For example:
#
# describe HacksHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe HacksHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackCode, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackSet, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Hack, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackUserCode, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackUserDebug, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe HackUserLastestCode, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save